__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も同様です した方が良い aでメソッドをエクスポートします def ファイル?
更新1
以下のように示す別のメソッド名で宣言をテストしました。
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" )
他のヒント
objbase.hの元の宣言には__declspec(dllexport)属性がなかったため、コンパイルしません。定義に追加することはできません。とにかく助けません、名前の装飾は適切ではありません。マイケルはあなたにそれについて何をすべきかを示しました。
手足に出て、イエスと言うつもりです。
Visual Studio 2008でさえ、ATL COM .DLLプロジェクトの.DEFファイルを自動的に生成します。