I am developing a COM dll and trying to export the DllGetClassObject() method with the __declspec(dllexport).
Here is my declaration:
extern "C" HRESULT __declspec(dllexport) __stdcall DllGetClassObject(REFCLSID rclsid,
REFIID riid, void** ppv)
But I kept get this error:
error C2375: 'DllGetClassObject' : redefinition; different linkage
So I try to check all the occurrence of the DllGetClassObject definitions. Thus found the following one in the ObjBase.h.
STDAPI DllGetClassObject(__in REFCLSID rclsid, __in REFIID riid, __deref_out LPVOID FAR* ppv);
the STDAPI turns out to be like this:
#define STDAPI EXTERN_C HRESULT STDAPICALLTYPE
in other words, it's like this:
#define STDAPI extern "C" HRESULT __stdcall
According to MSDN:
To export functions, the __declspec(dllexport) keyword must appear to the left of the calling-convention keyword, if a keyword is specified.
But my declaration mentioned before just didn't work.
I tested my declaration with a different method name, shown as below:
extern "C" HRESULT __declspec(dllexport) __stdcall f()
{
return S_OK;
}
And this method was exported successfully. So these specifiers could be used together. It seems the Visual C++ compiler takes STDAPI and extern "C" HRESULT __declspec(dllexport) __stdcall as not compatible.
This problem occurs I think because a __stdcall function (for 32-bit builds) is normally decorated with a underscore prefix and an @count
postfix. But if the function is also marked as __declspec(dllexport)
additional decorations are added (__imp
, I think).
You might be able to avoid using a .def file with the following pragma, if you're willing to live with the pragma (I think I'd go for the .def file):
#pragma comment( linker, "/export:DllGetClassObject=_DllGetClassObject@12" )
Note that for an x64 build, you might have to conditionally compile the pragma, which I think would be:
#pragma comment( linker, "/export:DllGetClassObject" )