Exportera och importera med hjälp av AFX_EXT_CLASS

DLL:er för MFC-tillägg använder makrot AFX_EXT_CLASS för att exportera klasser. de körbara filer som länkar till MFC-tilläggets DLL använder makrot för att importera klasser. Med makrot AFX_EXT_CLASS kan samma huvudfiler som används för att skapa MFC-tilläggets DLL användas med de körbara filer som länkar till DLL:en.

I huvudfilen för din DLL lägger du till nyckelordet AFX_EXT_CLASS i deklarationen för klassen på följande sätt:

class AFX_EXT_CLASS CMyClass : public CDocument
{
// <body of class>
};

Det här makrot definieras av MFC som __declspec(dllexport) när preprocessorsymbolerna _AFXDLL och _AFXEXT definieras. Men makrot definieras som __declspec(dllimport) när _AFXDLL har definierats och _AFXEXT har inte definierats. När den definieras anger symbolen för förprocessorn _AFXDLL att den delade versionen av MFC används av den körbara målversionen (antingen en DLL eller ett program). När både _AFXDLL och _AFXEXT definieras anger detta att det körbara målet är en MFC-tilläggs-DLL.

Eftersom AFX_EXT_CLASS definieras som __declspec(dllexport) när du exporterar från ett MFC-tilläggs-DLL kan du exportera hela klasser utan att placera de dekorerade namnen för alla den klassens symboler i def-filen.

Även om du kan undvika att skapa en .def-fil och alla de dekorerade namnen för klassen med den här metoden är det effektivare att skapa en .def-fil eftersom namnen kan exporteras med ordningstal. Om du vill använda .def-filmetoden för export placerar du följande kod i början och slutet av rubrikfilen:

#undef AFX_DATA
#define AFX_DATA AFX_EXT_DATA
// <body of your header file>
#undef AFX_DATA
#define AFX_DATA

Försiktighet

Var försiktig när du exporterar infogade funktioner, eftersom de kan skapa en risk för versionskonflikter. En infogad funktion expanderas till programkoden. Om du senare skriver om funktionen uppdateras den därför inte om inte själva programmet kompileras om. Normalt kan DLL-funktioner uppdateras utan att återskapa de program som använder dem.

Exportera enskilda medlemmar i en klass

Ibland kanske du vill exportera enskilda medlemmar i klassen. Om du till exempel exporterar en CDialog-derived-klass kanske du bara behöver exportera konstruktorn och anropet DoModal . Du kan använda AFX_EXT_CLASS för de enskilda medlemmar som du behöver exportera.

Till exempel:

class CExampleDialog : public CDialog
{
public:
   AFX_EXT_CLASS CExampleDialog();
   AFX_EXT_CLASS int DoModal();
   ...
   // rest of class definition
   ...
};

Eftersom du inte längre exporterar alla medlemmar i klassen kan du stöta på ytterligare ett problem på grund av hur MFC-makron fungerar. Flera av MFC:s hjälpmakron deklarerar eller definierar datamedlemmar. Därför måste dessa datamedlemmar också exporteras från din DLL.

Makrot definieras till exempel DECLARE_DYNAMIC på följande sätt när du skapar en MFC-tilläggs-DLL:

#define DECLARE_DYNAMIC(class_name) \
protected: \
   static CRuntimeClass* PASCAL _GetBaseClass(); \
public: \
   static AFX_DATA CRuntimeClass class##class_name; \
   virtual CRuntimeClass* GetRuntimeClass() const; \

Raden som börjar med statisk AFX_DATA deklarerar ett statiskt objekt i klassen. Om du vill exportera den här klassen korrekt och komma åt körningsinformationen från en körbar klient måste du exportera det här statiska objektet. Eftersom det statiska objektet deklareras med modifieraren AFX_DATA, behöver du bara definiera AFX_DATA som __declspec(dllexport), när du bygger din DLL och definiera det som __declspec(dllimport) när du bygger den körbara klienten. Eftersom AFX_EXT_CLASS det redan har definierats på det här sättet behöver du bara omdefiniera AFX_DATA för att vara samma som AFX_EXT_CLASS i din klassdefinition.

Till exempel:

#undef  AFX_DATA
#define AFX_DATA AFX_EXT_CLASS

class CExampleView : public CView
{
   DECLARE_DYNAMIC()
   // ... class definition ...
};

#undef  AFX_DATA
#define AFX_DATA

Eftersom MFC alltid använder symbolen AFX_DATA för dataobjekt som definieras i makrona fungerar den här tekniken för alla sådana scenarier. Det fungerar till exempel för DECLARE_MESSAGE_MAP.

Anmärkning

Om du exporterar hela klassen i stället för valda medlemmar i klassen exporteras statiska datamedlemmar automatiskt.

Vad vill du göra?

Vad vill du veta mer om?

Se även

Exportera från en DLL