Почему я не могу использовать __declspec (dllexport) для экспорта dllgetclassObject () из com dll?

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

  •  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.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top