kernel32.dll
以下の方法でサードパーティの DLL の関数をインポートするために使用しています。
private delegate bool MyDelegate(float[] floatArray, UInt16[] intArray);
private static MyDelegate MyDelegateCaller = null;
public static bool MyMethod(ref float[] floatArray, out UInt16[] intArray)
{
if(MyDelegateCaller == null)
{
IntPtr address = GetProcAddress(_dllHandle, "ExternalMethod");
MyDelegateCaller =
(MyDelegate)Marshal.GetDelegateForFunctionPointer(
address,
typeof(MyDelegate)
);
}
return MyDelegateCaller(floatArray, intArray); //*
}
デバッグしてステップ オーバーするとMyDelegateCaller
(で//*
)、期待どおりに配列が設定されます。ただし、コードを実行しただけでは、配列にデータが取り込まれません。
何が起こっているかについてのアイデアはありますか?
詳細情報: 実行時に DLL をアンロードおよび再ロードできるようにする必要があるため、DLL を呼び出すために PInvoke ではなくこのメソッドを使用しています。ステップオーバーの効果をシミュレートするためのテストとして、さまざまなスレッドで実行して遅延を追加しようとしました。DLL が独自のスレッドを作成していない限り、これらのメソッドのクロス スレッド呼び出しはありませんが、確認するために DLL のコードにアクセスすることはできません。
アップデート
だから私は次のことを試しました(ここから触発されました)
...
);
}
IAsyncResult result = MyDelegateCaller.BeginInvoke(floatArray, intArray, null, null);
while (!result.IsCompleted)
result.AsyncWaitHandle.WaitOne(1000, false); //**
result.AsyncWaitHandle.Close();
return MyDelegateCaller.EndInvoke(result);
}
ただし、//**
プログラムに到達すると、 System.ExecutionEngineException
.
ハック
コードが機能しました。
以前の更新から作業を削除し、のイベントを入れMyMethod
ました。ループオーバー。BackgroundWorker
DoWork
BackgroundWorker.IsBusy
エレガントではありませんが、当面はそうします。
より良い解決策は大歓迎です!