Esportazione e importazione tramite AFX_EXT_CLASS
Le DLL di estensione utilizzano la macro AFX_EXT_CLASS per esportare le classi, mentre gli eseguibili che si collegano alla DLL di estensione utilizzano la macro per importare le classi. Con la macro AFX_EXT_CLASS, gli stessi file di intestazione utilizzati per compilare la DLL di estensione possono essere utilizzati con gli eseguibili che si collegano alla DLL.
Nel file di intestazione per la DLL, aggiungere la parola chiave AFX_EXT_CLASS alla dichiarazione della classe, nel modo seguente:
class AFX_EXT_CLASS CMyClass : public CDocument
{
// <body of class>
};
Questa macro viene definita da MFC come __declspec(dllexport) quando vengono definiti i simboli del preprocessore _AFXDLL e _AFXEXT. La macro viene invece definita come __declspec(dllimport) quando _AFXDLL è definito e _AFXEXT non lo è. Quando è definito, il simbolo del preprocessore _AFXDLL indica che la versione condivisa di MFC viene utilizzata dall'eseguibile di destinazione, ovvero una DLL o un'applicazione. Quando sia _AFXDLL che _AFXEXT sono definiti, significa che l'eseguibile di destinazione è una DLL di estensione.
Poiché AFX_EXT_CLASS è definita come __declspec(dllexport) durante l'esportazione da una DLL di estensione, è possibile esportare un'intera classe senza inserire nel file def i nomi decorati di tutti i simboli di tale classe. Questo metodo è utilizzato nell'esempio DLLHUSK MFC.
Anche se questo metodo consente di evitare la creazione di un file def con tutti i nomi decorati della classe, la creazione di un file def è più efficace poiché i nomi possono essere esportati in base al valore ordinale. Per utilizzare il metodo di esportazione tramite file def, inserire il seguente codice all'inizio e alla fine del file di intestazione:
#undef AFX_DATA
#define AFX_DATA AFX_EXT_DATA
// <body of your header file>
#undef AFX_DATA
#define AFX_DATA
Avviso
Fare attenzione durante l'esportazione delle funzioni inline, poiché potrebbero creare conflitti di versione.Dato che una funzione inline viene espansa nel codice dell'applicazione, se viene successivamente riscritta non viene aggiornata nell'applicazione, a meno che non si ricompili l'applicazione stessa.In genere, le funzioni DLL possono essere aggiornate senza ricompilare le applicazioni che le utilizzano.
Esportazione di singoli membri in una classe
Talvolta può risultare utile esportare singoli membri della classe. Se si esporta, ad esempio, una classe derivata da CDialog, può essere sufficiente esportare il costruttore e la chiamata DoModal. È possibile utilizzare AFX_EXT_CLASS sui singoli membri da esportare.
Di seguito è riportato un esempio.
class CExampleDialog : public CDialog
{
public:
AFX_EXT_CLASS CExampleDialog();
AFX_EXT_CLASS int DoModal();
...
// rest of class definition
...
};
Poiché non si esportano tutti i membri della classe, può verificarsi un problema legato al funzionamento delle macro MFC. Molte macro di supporto MFC dichiarano o definiscono in realtà membri dati. È pertanto necessario esportare anche questi membri dati dalla DLL.
La macro DECLARE_DYNAMIC, ad esempio, viene definita nel modo seguente quando si compila una DLL di estensione:
#define DECLARE_DYNAMIC(class_name) \
protected: \
static CRuntimeClass* PASCAL _GetBaseClass(); \
public: \
static AFX_DATA CRuntimeClass class##class_name; \
virtual CRuntimeClass* GetRuntimeClass() const; \
La riga che inizia con static AFX_DATA dichiara un oggetto static all'interno della classe. Per esportare correttamente questa classe e accedere alle informazioni della libreria di runtime da un eseguibile client, è necessario esportare questo oggetto static. Poiché l'oggetto static viene dichiarato con il modificatore AFX_DATA, è sufficiente definire AFX_DATA come __declspec(dllexport) quando si compila la DLL e come __declspec(dllimport) quando si compila l'eseguibile client. Poiché AFX_EXT_CLASS è già definita in tal modo, è sufficiente ridefinire AFX_DATA come AFX_EXT_CLASS intorno alla definizione della classe.
Di seguito è riportato un esempio.
#undef AFX_DATA
#define AFX_DATA AFX_EXT_CLASS
class CExampleView : public CView
{
DECLARE_DYNAMIC()
// ... class definition ...
};
#undef AFX_DATA
#define AFX_DATA
Poiché MFC utilizza sempre il simbolo AFX_DATA sugli elementi di dati che definisce all'interno delle macro, questa tecnica è valida per tutti gli scenari di questo tipo, ad esempio DECLARE_MESSAGE_MAP.
Nota
Se si esporta l'intera classe anziché alcuni membri di essa, i membri dati statici vengono esportati automaticamente.
Scegliere l'argomento con cui si desidera procedere
Esportazione di funzioni C++ per l'utilizzo in eseguibili in linguaggio C
Esportazione di funzioni C per l'utilizzo in eseguibili in linguaggio C o C++
Importazione in un'applicazione utilizzando __declspec(dllimport)