DLLのインポートエントリを呼び出すことはできません、C#の - > C ++、EntryPointNotFoundException
-
20-09-2019 - |
質問
私はC ++で書かれたカスタムDLLでC#の関数から呼び出すようにしようとしています。しかし、私は、実行時にコード解析中に警告やエラーを取得しています:
警告:CA1400: Microsoft.Interoperability:正しいです の宣言 'SafeNativeMethods.SetHook()' となるよう それは正しく、既存指します 「wi.dll」のエントリポイント。管理されていません 現在にリンクされたエントリ・ポイント名 SetHookです。
エラー: System.EntryPointNotFoundExceptionました 未処理。エントリを見つけることができません。 DLL 'wi.dll' の 'SetHook' という名前のポイントます。
両方のプロジェクトがwi.dllとC#のexeファイルが同じDEBUGフォルダにしてコンパイルされている、両方のファイルはここに存在します。全体のファイルシステム内の名前wi.dllを持つ唯一のファイルがあります。
C ++関数の定義は次のようになります:
#define WI_API __declspec(dllexport)
bool WI_API SetHook();
私は、依存関係ウォーカーを使用してエクスポート機能を見ることができます:
as decorated: bool SetHook(void)
as undecorated: ?SetHook@@YA_NXZ
C#のDLLのインポートが(私はMSDNの雑誌からCLRInsideOutを使用して、これらの行を定義した)ように見えます
[DllImport("wi.dll", EntryPoint = "SetHook", CallingConvention = CallingConvention.Cdecl)]
[return: MarshalAsAttribute(UnmanagedType.I1)]
internal static extern bool SetHook();
私もエントリーポイントとCallingConvention定義せずに試してみた。
どちらのプロジェクトは、32ビットである、私はW7 64ビットで、VS 2010 RCを使用しています。
私は単に何かを見落としていることを信じて....
事前に感謝します。
解決
さて、あなたは、エントリポイントの名前を知って、エントリーポイント=を使用して[DLLIMPORT]属性にプロパティ「?@@ YA_NXZをSetHook」。または名前がマングルされませんので、あなたのC ++コードでの宣言の前にextern「C」を入れます。
[DllImport("wi.dll", EntryPoint = "?SetHook@@YA_NXZ", CallingConvention = CallingConvention.Cdecl)]
[return: MarshalAsAttribute(UnmanagedType.I1)]
internal static extern bool SetHook();
他のヒント
CallingConvention.Cdecl
はCではないC ++を意味し、あなたがC ++に装飾された名前の機能を持っているときに、あなたはEntryPoint
ように装飾名を使用するか、C ++の名前の装飾をオフにするためにC ++コード宣言内でextern「C」を使用する必要があります。