non è possibile ottenere l'indirizzo della funzione DLL con GetProcAddress
-
29-09-2019 - |
Domanda
Ho creato una DLL con VS C ++ (naturalmente come progetto DLL) con il seguente codice del file di intestazione:
#pragma once
#include <iostream>
#include "..\..\profiles/ProfileInterface.h"
using namespace std;
extern "C" __declspec(dllexport) class CExportCoordinator: public CProfileInterface
{
public:
CExportCoordinator(void);
virtual ~CExportCoordinator(void);
CProfileInterface* Create();
void Initialize();
void Start();
};
Ecco file cpp della DLL:
#include "StdAfx.h"
#include "ExportCoordinator.h"
CExportCoordinator::CExportCoordinator(void)
{
}
CExportCoordinator::~CExportCoordinator(void)
{
}
CProfileInterface* CExportCoordinator::Create(){
cout << "ExportCoordinator3 created..." << endl;
return new CExportCoordinator();
}
void CExportCoordinator::Initialize(){
cout << "ExportCoordinator3 initialized..." << endl;
}
void CExportCoordinator::Start(){
cout << "ExportCoordinator3 started..." << endl;
}
I esportato tutta la classe CExportCoordinator
perché ho bisogno di utilizzare tutti e tre i metodi che offre. Di seguito è riportato il codice dall'applicazione principale di carico del, sopra determinato, dll al volo.
typedef CProfileInterface* (WINAPI*Create)();
int _tmain(int argc, _TCHAR* argv[])
{
HMODULE hLib = LoadLibrary(name);
if(hLib==NULL) {
cout << "Unable to load library!" << endl;
return NULL;
}
char mod[MAXMODULE];
GetModuleFileName(hLib, (LPTSTR)mod, MAXMODULE);
cout << "Library loaded: " << mod << endl;
Create procAdd = (Create) GetProcAddress(hLib,"Create");
if (!procAdd){
cout << "function pointer not loaded";
}
return;
}
In uscita ottengo che la corretta libreria viene caricata, ma che puntatore a funzione procAdd
è NULL. Ho pensato che avesse qualcosa a che fare con il nome mangling e extern "C"
aggiunto quando si esporta la classe nell'intestazione di dll, ma nulla è cambiato. Btw, ho usato DLL Export Viewer per la visualizzazione delle funzioni esportate della classe, e il tutta la classe viene esportato correttamente.
Qualsiasi aiuto?
Aggiorna
c'è un errore nel file di intestazione di dll. Io non dovrebbero usare extern "C" __declspec(dllexport)
prima classe perché classe quindi non sarà esportato a tutti. Se uso class __declspec(dllexport) CExportCoordinator
allora la classe viene esportato correttamente, ma in ogni caso non riesco a ottenere l'indirizzo della funzione diverso da NULL.
Soluzione
extern "C" __declspec(dllexport) class CExportCoordinator: public CProfileInterface
{
Questa è una sciocchezza. Una classe non può essere "extern C"
... inside the class ...
CProfileInterface* Create();
Questo crea una funzione membro della classe, che probabilmente non è ciò che si desidera. Per prima cosa, sarà alterati nella DLL, secondo, non sarà richiamabile senza il puntatore this. Probabilmente, è necessario questa dichiarazione:
extern "C" __declspec(dllexport) CProfileInterface* Create();
e implemntation:
extern "C" __declspec(dllexport) CProfileInterface* Create(){
cout << "ExportCoordinator3 created..." << endl;
return new CExportCoordinator();
}
Altri suggerimenti
Mi sembra che si dovrebbe dichiarare metodo Create
come metodo static
ed esportare solo questo metodo. Se potrete soggiornare avere NULL
in GetProcAddress
è necessario esaminare le esportazioni di DLL rispetto di Dependency Walker (vedi http: // www .dependencywalker.com / ) e modificare il nome della funzione "Crea" per qualcosa come "_create" o "_create @ 2".