ac# アプリケーションからアンマネージ Dll を呼び出すと、AccessViolationException
. 奇妙なことに、エクスポートされた関数には引数がないため、問題はデータのマーシャリングにはありません。この関数は引数を取得せず、整数を返すだけです。また、呼び出し規約は問題ではないことに注意してください。同じゼロ引数と整数の戻り値 (ただし名前は異なる) を持つ同一の関数は問題なく動作します。マーシャリングと呼び出し規則が除外されているという事実を考慮して、そのような呼び出しがこの例外を引き起こす可能性がある残りの候補となる理由は何ですか?
更新: プレーン リンクを介して他のアンマネージ コードから呼び出された場合、完全に機能するため、dll 関数は正しいです。
更新 2: すべてがコンパイルされ、32 ビットで実行されます。Windows XP SP2 と Vista を試しました。ここに興味深い事実があります。Vista システムでは、これは魔法のように機能します。XPでは失敗します。
更新 3: ソース コードを入手できませんでしたが、この dll が本質的に何をするかを知ったので、自分の dll で問題を再現しようとしました。ここに話があります: 元の dll は、ei.lib (Erlang の c インターフェイス ライブラリ) へのある種のラッパーです。いくつかのヘルパー関数をエクスポートします。したがって、問題を再現するために、「test()」という 1 つの関数のみをエクスポートする ei.lib のラッパー dll を作成しました。マーシャリングなどを台無しにしないように、そうしました。初期化、接続、メッセージの送信をテストしたかっただけです。したがって、この dll の test() func は、 を呼び出してei_connect_init()
から、最後ei_connect()
にei_reg_send()
、内部にハードコードされた引数を持ちます。問題は、この dll を呼び出して別のアンマネージ コードから test() 関数を使用すると、問題なく動作することです。メッセージが送信されます。しかし、DllImport を介して c# から呼び出すと、Vista でのみ機能します。XPではありません。XP では、.net 層で AccessViolationException で失敗します。私は問題を追跡しようとしましたが、XP で実行されていてマネージ コードによって呼び出されている場合、dll 内から への呼び出しei_connect()
、または読み取りの試みerl_errno
(これらは ei.lib で定義されています) が読み取ろうとしていることがわかります。または、アプリがクラッシュするように保護されたメモリを書き込みます。Vistaで動作し、アンマネージコードから呼び出されたときに動作するため、些細なことではありません。