Per realizzare il linking dinamico, abbiamo bisogno di dichiarare le funzioni membro della classe come virtual.
La DLL deve inoltre implementare una funzione (nell'esempio sotto la funzione è GetClasse) che crea l'oggetto e ne restituisce il puntatore.
Nel programma client dichiariamo un puntatore alla classe e lo inizializziamo richiamando la funzione nella DLL.
Header file della DLL:
Implementazione della DLL:codice:#ifdef EXPORTCLASSFROMDLL_EXPORTS #define EXPORTCLASSFROMDLL_API __declspec(dllexport) #else #define EXPORTCLASSFROMDLL_API __declspec(dllimport) #endif #ifdef __cplusplus extern "C" { #endif // This class is exported from the ExportClassFromDll.dll class EXPORTCLASSFROMDLL_API CExportClassFromDll { public: CExportClassFromDll(void); // TODO: add your methods here. virtual int GetValue(); private: int x; }; EXPORTCLASSFROMDLL_API CExportClassFromDll * GetClasse(); #ifdef __cplusplus } #endif
Nel programma client utilizziamo le funzioni per il linking dinamico LoadLibrary e GetProcAddress:codice:#define EXPORTCLASSFROMDLL_EXPORTS #include "ExportClassFromDll.h" // This is the constructor of a class that has been exported. // see ExportClassFromDll.h for the class definition CExportClassFromDll::CExportClassFromDll() { x = 21; return; } int CExportClassFromDll::GetValue() { return x; } EXPORTCLASSFROMDLL_API CExportClassFromDll * GetClasse() { return new CExportClassFromDll(); }
codice:#include <windows.h> #include <iostream> using namespace std; #include "ExportClassFromDll.h" typedef CExportClassFromDll* (*GETCLASSE_POINTER)(); int main(void) { GETCLASSE_POINTER pfnGetClasse = NULL; CExportClassFromDll * pmyCLassFromDll = NULL; // Carichiamo dinamicamente la DLL HINSTANCE hMyDll = ::LoadLibrary("ExportClassFromDll.dll"); if(hMyDll != NULL) { // Otteniamo il puntatore alla funzione GetClasse pfnGetClasse = (GETCLASSE_POINTER)::GetProcAddress(hMyDll, "GetClasse"); // Se il puntatore è nullo, rilasciamo la DLL e usciamo if(pfnGetClasse == 0) { ::FreeLibrary(hMyDll); printf("Errore nel puntatore alla funzione GetClasse\n"); return -1; } // Se invece il puntatore è valido, richiamiamo la funzione facendoci // restituire il puntatore alla classe pmyCLassFromDll = pfnGetClasse(); if ( !pmyCLassFromDll ) // Se GetClasse restituisce un puntatore nullo, usciamo { ::FreeLibrary(hMyDll); printf("Errore nel puntatore alla classe\n"); return -1; } // se invece il puntatore alla classe è valido, lo utilizziamo cout << pmyCLassFromDll->GetValue() << endl; // liberiamo la memoria delete pmyCLassFromDll; // Rilasciamo la DLL ::FreeLibrary(hMyDll); } else { printf("Errore nel caricamento della DLL ExportClassFromDll.dll\n"); } return 0; }![]()

Rispondi quotando