Я занимаюсь разработкой 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
другими словами, это так: Ключевое слово __declspec (dllexport) должно появиться слева от ключевое слово соглашения о вызовах, если задано ключевое слово.
Но мое объявление, упомянутое ранее, просто не сработало.
Я проверил свое объявление с другим именем метода, показанным ниже:
extern "C" HRESULT __declspec(dllexport) __stdcall f()
{
return S_OK;
}
И этот метод был успешно экспортирован. Таким образом, эти спецификаторы могут быть использованы вместе. Похоже, что компилятор Visual C ++ считает STDAPI и extern "C" HRESULT __declspec (dllexport) __stdcall как несовместимые.
Я думаю, эта проблема возникает из-за того, что функция __stdcall (для 32-битных сборок) обычно украшается префиксом подчеркивания и постфиксом @count
. Но если функция также помечена как __ declspec (dllexport)
, добавляются дополнительные украшения ( __ imp
, я думаю).
Возможно, вам удастся избежать использования файла .def с помощью следующей прагмы, если вы хотите жить с прагмой (я думаю, что я бы выбрал файл .def):
#pragma comment( linker, "/export:DllGetClassObject=_DllGetClassObject@12" )
Обратите внимание, что для x64, вам, возможно, придется условно скомпилировать прагму, которая, я думаю, будет такой:
#pragma comment( linker, "/export:DllGetClassObject" )
Я рискну и скажу «да».
Даже Visual Studio 2008 автоматически генерирует файл .def для проектов ATL COM .dll.
Он не компилируется, потому что исходное объявление в objbase.h не имело атрибута __declspec (dllexport). Вы не можете добавить это в определение. Все равно не поможет, именное украшение неуместно. Майкл показал вам, что с этим делать.