C#P /呼び出すためにC ++ DLLから関数をエクスポートします
質問
私はC#のコードから呼び出すしたいC ++ DLLを構築しています。私は1つの関数を呼び出すことができるんだけど、C#のコードは、DLLをロードしようとしたとき、他のは、例外をスローします。
ヘッダーは次のようになります:
extern "C" __declspec(dllexport) BOOL Install();
extern "C" __declspec(dllexport) BOOL PPPConnect();
このは(FOO = fooは名前欄に何を意味するのでしょうか?)少し混乱輸出テーブルとDLLを生成します:
File Type: DLL
Section contains the following exports for PPPManager.dll
00000000 characteristics
499F44F0 time date stamp Fri Feb 20 16:04:00 2009
0.00 version
1 ordinal base
2 number of functions
2 number of names
ordinal hint RVA name
1 0 000078E4 Install = Install
2 1 000079DC PPPConnect = PPPConnect
私のP /呼び出しの宣言は次のようになります
[DllImport("PPPManager.dll")]
private static extern bool Install();
[DllImport("PPPManager.dll")]
private static extern bool PPPConnect();
例外なくリターンをインストールするための呼び出しを、私はPPPConnectを呼び出すときに、私はMissingMethodExceptionを得る - 「のPInvoke DLL 『PPPManager.dll』内のエントリポイント 『PPPConnect』が見つかりません。」
PPPConnectがエクスポート機能だけであり、これはまだ私がPPPConnectを呼び出すことはできませんように、私は、インストール関数の宣言からはexternとdeclspecディレクティブを削除しようとしました。
私はまた序によりDLLIMPORTをやって試してみました。これは名前で呼び出したのと同じ結果になります - 。リターンをインストールします。ただし、PPPConnectは例外「エントリポイント 『#2』を見つけることができません...」をスローします。
相互運用ログを与えます:
[pinvokeimpl][preservesig]
bool invivodata.Common.System.IPAQUtils::Install();
BOOLEAN (I1_WINBOOL_VAL) Install();
JIT ERROR FOR PINVOKE METHOD (Managed -> Native):
[pinvokeimpl][preservesig]
bool invivodata.Common.System.IPAQUtils::PPPConnect();
BOOLEAN (I1_WINBOOL_VAL) PPPConnect();
これは専門知識の私の領域の外側にもあるので、任意の提案や考えは歓迎されるでしょう。
おかげで、 ポール
編集: それは、このコードは、作業を行うことが判明しました。問題はデバイスに伝播されていない最新のdllとありました。 D'OH!
解決
あなたはこれらの機能をエクスポートするために、あなたのDLLプロジェクトに.defファイルを使用していますか?もしそうなら、それを削除し、再試行してください。あなたの輸出は、あなたがにextern「C」declspec(dllexports)を行うときに、彼らがどうあるべきかではないように見えるので、これは単なる推測です。
私が使用して簡単なC ++のdllでこれを試してみた。
extern "C" __declspec(dllexport) BOOL Install();
extern "C" __declspec(dllexport) BOOL PPPConnect();
とシンプルなC#のアプリは、あなたのPInvoke宣言がを使用して、それがうまく働いた。の
私がやったときDUMPBIN /私が見たDLLの輸出ます:
ファイルPPPManager.dllのダンプ
ファイルタイプ:DLL
セクションPPPManager.dllのため、次の輸出が含まれています。
00000000 characteristics
499F6C2D time date stamp Fri Feb 20 20:51:25 2009
0.00 version
1 ordinal base
2 number of functions
2 number of names
ordinal hint RVA name
1 0 000110CD Install = @ILT+200(_Install)
2 1 00011069 PPPConnect = @ILT+100(_PPPConnect)
エクスポートされた名前は私の場合で異なっていることに注意してください。
他のヒント
これは、OSによって誤解ます方法で失敗しPPPConnect
のような単純なものである可能性があります。空命令としてInstall
とPPPConnect
の両方を実装してみて、エラーが続くかどうかを確認し(ちょうどそれらが他に何もせずTRUE
を返すがあります)。もしそうなら、彼らは(空命令としてまだ)エクスポートされる順序を交換してみてください、問題がまたは何か他のものに(そう)発注に結びついているかどうかを確認します。
また、DLLの輸出テーブルがどのように見えるかを確認するためのグラフィカルツールdepends
を使用することができますが、私は問題は、これらの方面から来ている疑います。
あなたの説明によると、インストールおよびPPPConnectは名前だけが異なります。私は、あなたは、単にあなたのC#アプリケーションで古い.dllファイルのバージョンを使用すると思います。定義されたPPPConnectないもの。
宣言は(私はソースなしで判断できる限り)、右に見えます。
グレート情報が、あなたが言及として、すべてがここにオーダーです。 Windows用デバッグツールをインストールして実行してみます:
kd -z \path\to\PPPManager.dll -y \path\to\PPPManager.pdb -c "x pppmodule!*"
シンボルテーブルのより良いダンプを取得します。それは同様にブラインドショットですが、あなたも試みることができる:
extern "C"
{
__declspec(dllexport) BOOL Install();
__declspec(dllexport) BOOL PPPConnect();
};
の場合には__declspecは奇妙な何かをやっている。
タグ使用可能な方法を確認するために、依存関係ウォーカーを使用して、DLLを開きます