サードパーティのネイティブ C dll を使用するアプリケーションがあります。.Net 4 を搭載した Windows 7 マシンではすべて正常に動作しますが、.Net 4 を搭載した Windows XP (SP3) では失敗します。
Windows XP マシンで次の例外が発生します。
未処理の例外: System.AccessViolationException: 保護されたメモリの読み取りまたは書き込みを試みました。これは多くの場合、他のメモリが破損していることを示しています。
デバッグすると、
CacheInteropTest.exe の 0x10069e1d での初回例外: 0xC0000005: アクセス違反の読み取り場所 0x00000000。
これは私の単純化されたテスト アプリケーション コードです。
public unsafe class Program
{
[STAThread]
static void Main(string[] args)
{
var status = CacheEnd();
Console.ReadKey(true);
}
[SuppressUnmanagedCodeSecurity]
[DllImport("cachet.dll", EntryPoint = "#24", CallingConvention = CallingConvention.Cdecl, SetLastError = true)]
internal extern static int CacheEnd();
}
上記のプログラムを Windows XP (SP3) 32 ビットでコンパイルし、Windows 7 マシンにコピーして実行しましたが、例外は発生しませんでした。サード パーティの dll は、実行可能ファイルと同じフォルダーにあります。
AccessViolationException に関連する問題に対する多くの回答を見つけました。特に、この
AccessViolationException in P/Invoke 呼び出しはほぼ一致しています。別のサイトには、PInvoke とメモリ関連の問題に関する概要が記載されています
http://dotnetdebug.ne t/2006/04/17/pinvoke-and-memory-related-issues/ です が、この場合は役に立ちません。
サード パーティの dll はデータベース カーネルであり、マルチスレッド データベース アクセスを提供します (スレッドごとに 1 つの接続を維持します)。API のドキュメントでは、dll を静的にリンクする必要があり、Windows XP でこの dll を使用する C++ アプリケーションも適切に機能することが記載されています。
問題はネイティブ dll の実装にあると思いますが、なぜ Windows 7 でうまく動作するのでしょうか。
Windows XP で何がうまくいかないのか、誰にもわかりませんか?
ベンダーが提供するネイティブ関数のプロトタイプ タイプは、
extern int CFPROTOD(CacheEnd,(void));
したがって、この問題は呼び出し規約とは関係ないと思います。