Why can't I use __declspec(dllexport) to export DllGetClassObject() from a COM DLL?

StackOverflow https://stackoverflow.com/questions/3460533

  •  27-09-2019
  •  | 
  •  

문제

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.

So does COM DLL have to export their methods with a def file?


Update 1

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" )

다른 팁

It doesn't compile because the original declaration in objbase.h didn't have the __declspec(dllexport) attribute. You cannot add it in the definition. Won't help anyway, the name decoration isn't appropriate. Michael showed you what to do about that.

I'm going to go out on a limb and say yes.

Even Visual Studio 2008 automatically generates the .def file for ATL COM .dll projects.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top