Почему я не могу использовать __declspec (dllexport) для экспорта DllGetClassObject () из COM DLL? - PullRequest
9 голосов
/ 11 августа 2010

Я разрабатываю COM DLL и пытаюсь экспортировать метод DllGetClassObject () с помощью __ declspec (dllexport) .

Вот мое заявление:

extern "C" HRESULT __declspec(dllexport) __stdcall DllGetClassObject(REFCLSID rclsid, 
                                                             REFIID riid, void** ppv)

Но я продолжал получать эту ошибку:

error C2375: 'DllGetClassObject' : redefinition; different linkage

Поэтому я пытаюсь проверить все вхождения определений DllGetClassObject. Таким образом, нашел следующий файл в ObjBase.h .

STDAPI  DllGetClassObject(__in REFCLSID rclsid, __in REFIID riid, __deref_out LPVOID FAR* ppv);

STDAPI оказывается таким:

#define STDAPI                  EXTERN_C HRESULT STDAPICALLTYPE

другими словами, это так:

#define STDAPI                  extern "C" HRESULT __stdcall

Согласно MSDN :

Для экспорта функций Ключевое слово __declspec (dllexport) должно появиться слева от ключевое слово соглашения о вызовах, если указано ключевое слово.

Но мое заявление, упомянутое ранее, просто не сработало.

Так что же COM DLL должен экспортировать свои методы с файлом def ?


Обновление 1

Я проверил мое объявление с другим именем метода, показанным ниже:

extern "C" HRESULT __declspec(dllexport) __stdcall f()
{
    return S_OK;
}

И этот метод был успешно экспортирован. Таким образом, эти спецификаторы могут быть использованы вместе. Похоже, компилятор Visual C ++ принимает STDAPI и extern "C" HRESULT __declspec (dllexport) __stdcall как несовместимые.

Ответы [ 3 ]

9 голосов
/ 11 августа 2010

Эта проблема возникает, я думаю, потому что функция __stdcall (для 32-битных сборок) обычно украшена префиксом подчеркивания и постфиксом @count.Но если функция также помечена как __declspec(dllexport), добавляются дополнительные декорации (я думаю, __imp).

Возможно, вы сможете избежать использования файла .def со следующей прагмой, если выжелая жить с прагмой (думаю, я бы пошел на файл .def):

#pragma comment( linker, "/export:DllGetClassObject=_DllGetClassObject@12" )

Обратите внимание, что для сборки x64 вам, возможно, придется условно скомпилировать прагму, что, я думаю:

#pragma comment( linker, "/export:DllGetClassObject" )
3 голосов
/ 11 августа 2010

Он не компилируется, потому что исходное объявление в objbase.h не имело атрибута __declspec (dllexport).Вы не можете добавить его в определение.Ничего не поможет, название украшения не подходит.Майкл показал тебе, что с этим делать.

0 голосов
/ 11 августа 2010

Я собираюсь выйти из строя и сказать «да».

Даже Visual Studio 2008 автоматически создает файл .def для проектов ATL COM .dll.

...