Exportování a importování pomocí AFX_EXT_CLASS
Knihovny DLL rozšíření používají makro AFX_EXT_CLASS pro exportování tříd; spustitelné soubory, které se připojují ke knihovně DLL rozšíření používají makro pro importování tříd. S makrem AFX_EXT_CLASS mohou být použity stejné hlavičkové soubory, které slouží k sestavení rozšiřující knihovny DLL, se spustitelnými soubory, které se připojují na knihovnu DLL.
V hlavičkovém souboru pro vaši knihovnu DLL přidejte klíčové slovo AFX_EXT_CLASS k deklaraci vaší třídy takto:
class AFX_EXT_CLASS CMyClass : public CDocument
{
// <body of class>
};
Toto makro je definováno knihovnou MFC jako __declspec(dllexport), když jsou definovány symboly preprocesoru _AFXDLL a _AFXEXT. Ale makro je definováno jako __declspec(dllimport), když je definováno _AFXDLL a není definováno _AFXEXT. Když je definován, symbol preprocesoru _AFXDLL označuje, že sdílená verze knihovny MFC je používána cílovým spustitelným souborem (buď knihovna DLL nebo aplikace). Když je definován jak _AFXDLL tak _AFXEXT, znamená to, že cílový spustitelný soubor je rozšiřující knihovna DLL.
Protože je AFX_EXT_CLASS definován jako __declspec(dllexport) při exportování z rozšiřující knihovny DLL, můžete exportovat celé třídy bez umístění dekorovaných názvů pro všechny tyto symboly třídy v souboru .def. Tato metoda se používá v ukázce knihovny MFC DLLHUSK.
Ačkoli se můžete touto metodou vyhnout vytvoření souboru .def a všem dekorovaným názvům pro třídu, vytvoření souboru .def je efektivnější, protože názvy je možné exportovat podle pořadí. Pro použití metody exportování pomocí souboru .def umístěte následující kód na začátek a konec vašeho souboru hlaviček:
#undef AFX_DATA
#define AFX_DATA AFX_EXT_DATA
// <body of your header file>
#undef AFX_DATA
#define AFX_DATA
Upozornění |
---|
Buďte opatrní při exportu vložených funkcí, protože mohou vytvořit možnost konfliktu verzí. Vložená funkce je rozšířena do kódu aplikace; proto pokud později přepíšete funkci, neprovede se její aktualizace dokud nepřeložíte aplikaci, která tuto funkci využívá . Obvykle lze aktualizovat funkce knihovny DLL bez nutnosti opětovného sestavení aplikace, která tyto funkce používá. |
Exportování jednotlivých členů ve třídě
Někdy můžete chtít exportovat jednotlivé členy vaší třídy. Například pokud exportujete třídu odvozenou od CDialog, můžete potřebovat exportovat pouze konstruktor a volání DoModal. Můžete použít AFX_EXT_CLASS u jednotlivých členů, které potřebujete exportovat.
Příklad:
class CExampleDialog : public CDialog
{
public:
AFX_EXT_CLASS CExampleDialog();
AFX_EXT_CLASS int DoModal();
...
// rest of class definition
...
};
Protože již neexportujete všechny členy třídy, můžete se dostat do dalšího problému z důvodu způsobu práce maker knihovny MFC. Několik podpůrných maker knihovny MFC ve skutečnosti deklaruje nebo definuje datové členy. Proto musí být tyto datové členy rovněž exportovány z vaší knihovny DLL.
Například makro DECLARE_DYNAMIC je definováno takto při vytváření rozšiřující knihovny DLL:
#define DECLARE_DYNAMIC(class_name) \
protected: \
static CRuntimeClass* PASCAL _GetBaseClass(); \
public: \
static AFX_DATA CRuntimeClass class##class_name; \
virtual CRuntimeClass* GetRuntimeClass() const; \
Řádek, který začíná statickým AFX_DATA je deklarování statického objektu uvnitř vaší třídy. Pro správné exportování této třídy a přístup k informacím za běhu z klientského spustitelného souboru je nutné exportovat tento statický objekt. Protože je statický objekt deklarován s modifikátorem AFX_DATA, potřebujete pouze definovat AFX_DATA na __declspec(dllexport), při sestavování vaší knihovny DLL, a definovat jej jako __declspec(dllimport), při sestavování vašeho klientského spustitelného souboru. Protože již je AFX_EXT_CLASS tímto způsobem definován, musíte pouze předefinovat AFX_DATA tak, aby byl stejný jako AFX_EXT_CLASS kolem definice vaší třídy.
Příklad:
#undef AFX_DATA
#define AFX_DATA AFX_EXT_CLASS
class CExampleView : public CView
{
DECLARE_DYNAMIC()
// ... class definition ...
};
#undef AFX_DATA
#define AFX_DATA
Vzhledem k tomu, že knihovna MFC vždy používá symbol AFX_DATA na datových položkách, které definuje v rámci jejích maker, funguje tento postup u všech scénářů. Například funguje pro DECLARE_MESSAGE_MAP.
Poznámka
Chcete-li exportovat celou třídu, nikoli pouze vybrané členy dané třídy, jsou statické datové členy automaticky exportovány.
Co chcete udělat?
Export funkcí jazyka C++ pro použití ve spustitelných souborech jazyka C
Export funkcí jazyka C pro použití ve spustitelných souborech jazyka C nebo jazyka C++