C#コードから呼び出したいC++dllを作成しました。1つの関数を呼び出すことはできますが、C#コードがdllを読み込もうとすると、もう1つの関数が例外をスローします。
ヘッダーは次のようになります。
extern "C" __declspec(dllexport) BOOL Install();
extern "C" __declspec(dllexport) BOOL PPPConnect();
これにより、エクスポートテーブルが少しわかりにくいdllが生成されます(名前フィールドでfoo = fooはどういう意味ですか?):
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/Invoke宣言は次のようになります。
[DllImport("PPPManager.dll")]
private static extern bool Install();
[DllImport("PPPManager.dll")]
private static extern bool PPPConnect();
Installの呼び出しは例外なく返されますが、PPPConnectを呼び出すと、MissingMethodExceptionが発生します-「PInvokeDLL'PPPManager.dll'にエントリポイント'PPPConnect'が見つかりません。」
Install関数宣言からexternおよびdeclspecディレクティブを削除しようとしました。これにより、エクスポートされる関数はPPPConnectだけになりますが、それでもPPPConnectを呼び出すことはできません。
また、序数でDllImportを実行してみました。これにより、名前で呼び出すのと同じ結果が得られます。Installは戻りますが、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!