Používání příkazů dllimport a dllexport ve třídách jazyka C++

 

Nejnovější dokumentaci k sadě Visual Studio 2017 najdete tady.

Můžete deklarovat třídy jazyka C++ s atributem dllimport nebo dllexport. Tyto formy vyjadřuje, že je celá třída importovaná nebo exportovaná. Třídy exportované tímto způsobem se nazývají exportovatelné třídy.

Následující příklad definuje exportovatelnou třídu. Všechny členské funkce a statická data jsou exportovány:

#define DllExport   __declspec( dllexport )  
  
class DllExport C {  
   int i;  
   virtual int func( void ) { return 1; }  
};  

Všimněte si, že explicitní použití atributů dllimport a dllexport členů exportovatelné třídy je zakázáno.

Pokud deklarujete třídu dllexport, jsou exportovány všechny členské funkce a statické datové členy. Musíte zadat definice všech těchto členů ve stejném programu. Jinak dojde k chybě propojovacího programu. Jedinou výjimkou z tohoto pravidla platí pro čistě virtuální funkce, pro které nemusíte poskytnout explicitní definice. Protože však destruktor abstraktní třídy je vždy volán destruktorem základní třídy, čistě virtuální destruktory musí vždy poskytnout definici. Všimněte si, že tato pravidla jsou stejné pro neexportovatelné třídy.

Pokud exportujete data typu nebo funkce třídy, které vracejí třídy, je nutné exportovat třídy.

Pokud deklarujete třídu dllimport, jsou importovány všechny členské funkce a statické datové členy. Na rozdíl od chování dllimport a dllexport pro typy nonclass, statické datové členy nelze zadat definovat ve stejném programu, ve kterém je definována třída dllimport.

Všechny základní třídy exportovatelné třídy musí být exportovatelné. V opačném případě bude vyvoláno upozornění kompilátoru. Kromě toho musí být možné exportovat také všechny dostupné členy, kteří jsou zároveň třídami. Toto pravidlo povoluje třídu dllexport, která dědí z třídy dllimport a třídu dllimport, která dědí z třídy dllexport (i když se tento případ nedoporučuje). Je pravidlem, že vše, co je přístupné pro klienta knihovny DLL (podle pravidel přístupu jazyka C++), by mělo být součástí rozhraní, které lze exportovat. Jedná se o privátní členy dat zmiňované ve vložených funkcích.

Vzhledem k tomu, že členské funkce a statická data v rámci třídy mají implicitně externí propojení, můžete je deklarovat pomocí atributů dllimport nebo dllexport, pokud není exportována celá třída. Pokud je je celá třída importovaná nebo exportovaná, explicitní deklarace členské funkce a dat jako dllimport nebo dllexport je zakázána. Pokud deklarujete statického datového člena v rámci definice třídy jako dllexport, definice musí být někde v rámci stejného programu (jako u externího propojení nonclass).

Podobně můžete deklarovat členské funkce s využitím atributů dllimport nebo dllexport. V tomto případě je nutné zadat definici dllexport někde ve stejném programu.

Je vhodné si uvědomit několik důležitých bodů týkajících se importu a exportu selektivních členů:

  • Import a export výběrových členů je nejvhodnější pro poskytování verze exportované třídy rozhraní, která je více omezující, tedy taková, pro kterou můžete navrhnout knihovnu DLL, která omezí viditelnost veřejných a soukromých funkcí, které by jazyk jinak neomezil. Je také vhodný pro optimalizaci exportovatelného rozhraní: pokud víte, že klient podle definice nelze získat přístup k některým osobním datům, není nutné exportovat celé třídy.

  • Při exportu jedné virtuální funkce ve třídě můžete exportovat všechny nebo poskytnout alespoň verze, které může klient použít přímo.

  • Pokud máte třídu, ve které používáte selektivní členské import/export s virtuálními funkcemi, funkce musí být v rozhraní exportovatelné nebo definované jako inline (viditelné pro klienta).

  • Pokud definujete člena jako dllexport, ale nezahrnete ho do definice třídy, bude vygenerována chyba kompilátoru. Musíte definovat člena v záhlaví třídy.

  • Ačkoli je definice členů třídy jako dllimport nebo dllexport povolena, nemůžete přepsat rozhraní určené v definici třídy.

  • Pokud definujete členskou funkci na jiném místě, než je základní text definice třídy, ve kterém jste ji deklarovali, bude vyvoláno upozornění v případě, že funkce je definována jako dllexport nebo dllimport (pokud se tato definice liší od uvedené v deklaraci třídy).

Specificka produktu Microsoft END

dllexport, dllimport

Zobrazit: