Почему я не могу использовать __declspec (dllexport) для экспорта dllgetclassObject () из com dll?
-
27-09-2019 - |
Вопрос
Я разрабатываю 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 придется экспортировать свои методы с помощью деф файл?
Обновление 1.
Я проверил мою декларацию с другим именем метода, показанным ниже:
extern "C" HRESULT __declspec(dllexport) __stdcall f()
{
return S_OK;
}
И этот метод был успешно экспортирован. Таким образом, эти спецификаторы могут быть использованы вместе. Похоже, визуальный компилятор 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" )
Другие советы
Он не скомпилируется, потому что исходное декларация в objbase.h не было атрибута __declspec (dllexport). Вы не можете добавить его в определение. В любом случае не поможет, украшение имени не подходит. Майкл показал вам, что делать с этим.
Я собираюсь выйти на конечность и сказать да.
Даже Visual Studio 2008 автоматически генерирует файл .def для проектов ATL COM .dll.