Почему я не могу использовать declspec(dllexport) для экспорта DllGetClassObject() из COM-библиотеки DLL?
Я разрабатываю 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
in другими словами, это так:
#define STDAPI extern "C" HRESULT __stdcall
по данным MSDN:
для экспорта функций _Ключевое слово _declspec(dllexport) должно отображаться слева от ключевое слово calling-convention, если a указывается ключевое слово.
но моя декларация, упомянутая ранее, просто не сработала.
так делает COM DLL обязательно экспортировать свои методы с def файл?
обновление 1
Я проверил свою декларацию с другим именем метода, показанным ниже:
extern "C" HRESULT __declspec(dllexport) __stdcall f()
{
return S_OK;
}
и этот метод был успешно экспортирован. Таким образом, эти спецификаторы могут использоваться вместе. Кажется, компилятор Visual C++ принимает STDAPI и extern " C " HRESULT _ _ declspec (dllexport) __stdcall как не совместимы.
3 ответов
эта проблема возникает, я думаю, потому что функция __stdcall (для 32-разрядных сборок) обычно украшена префиксом подчеркивания и @count
постфикс. Но если функция помечена как __declspec(dllexport)
добавлены дополнительные украшения (__imp
, Я думаю).
возможно, вы сможете избежать использования a .def файл со следующей прагмой, если вы готовы жить с прагмой (я думаю, что я бы пошел на это .def file):
#pragma comment( linker, "/export:DllGetClassObject=_DllGetClassObject@12" )
обратите внимание, что для сборки x64 у вас может быть чтобы условно скомпилировать прагму, которая, я думаю, будет:
#pragma comment( linker, "/export:DllGetClassObject" )
Он не компилируется, потому что исходное объявление в objbase.H не имел атрибута __declspec(dllexport). Вы не можете добавить его в определении. В любом случае, название не подходит. Майкл показал тебе, что с этим делать.
Я собираюсь пойти на риск и сказать "да".
даже Visual Studio 2008 автоматически создает .def файл для ATL COM .проект DLL.