Perché non è possibile utilizzare __declspec (dllexport) per esportare DllGetClassObject () da una DLL COM?
-
27-09-2019 - |
Domanda
sto sviluppando un DLL COM e cercando di esportare il metodo DllGetClassObject () con il __ declspec (dllexport) .
Ecco la mia dichiarazione:
extern "C" HRESULT __declspec(dllexport) __stdcall DllGetClassObject(REFCLSID rclsid,
REFIID riid, void** ppv)
Ma ho continuato a ottenere questo errore:
error C2375: 'DllGetClassObject' : redefinition; different linkage
Quindi cerco di controllare tutti la presenza delle definizioni DllGetClassObject. Così trovato la seguente nella sezione OBJBASE.H .
STDAPI DllGetClassObject(__in REFCLSID rclsid, __in REFIID riid, __deref_out LPVOID FAR* ppv);
lo STDAPI si rivela in questo modo:
#define STDAPI EXTERN_C HRESULT STDAPICALLTYPE
In altre parole, è come questo:
#define STDAPI extern "C" HRESULT __stdcall
MSDN :
funzioni di esportazione verso la __declspec (dllexport) deve apparire a sinistra del calling-convention parola chiave, se un viene specificata parola chiave.
Ma la mia dichiarazione accennato prima semplicemente non ha funzionato.
Così fa DLL COM Sono d' esportare i loro metodi con un def file?
Aggiornamento 1
ho provato la mia dichiarazione con un diverso nome di metodo, indicato come di seguito:
extern "C" HRESULT __declspec(dllexport) __stdcall f()
{
return S_OK;
}
E questo metodo è stato esportato con successo. Così questi specificatori potrebbero essere utilizzati insieme. Sembra che il compilatore Visual c ++ prende STDAPI e extern "C" HRESULT __declspec (dllexport) __stdcall non compatibili.
Soluzione
Questo problema si verifica Credo perché una funzione __stdcall (per 32 bit costruisce) è normalmente decorato con un prefisso di sottolineatura e un suffisso @count
. Ma se la funzione è anche contrassegnato come __declspec(dllexport)
sono aggiunte decorazioni aggiuntive (__imp
, credo).
Si potrebbe essere in grado di evitare l'uso di un file .def con il seguente pragma, se siete disposti a vivere con il pragma (credo mi piacerebbe andare per il file DEF):
#pragma comment( linker, "/export:DllGetClassObject=_DllGetClassObject@12" )
Si noti che per una generazione x 64, potrebbe essere necessario condizionare la compilazione del pragma, che credo potrebbe essere:
#pragma comment( linker, "/export:DllGetClassObject" )
Altri suggerimenti
Non ha compilato perché la dichiarazione originale in OBJBASE.H non ha avuto l'attributo __declspec (dllexport). Non è possibile aggiungere che nella definizione. non aiuterà in ogni caso, la decorazione nome non è appropriato. Michael ha mostrato che cosa fare al riguardo.
ho intenzione di andare su un arto e dire di sì.
Anche Visual Studio 2008 genera automaticamente il file .def per ATL COM dll progetti.