1

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ました。ループオーバー。BackgroundWorkerDoWorkBackgroundWorker.IsBusy

エレガントではありませんが、当面はそうします。

より良い解決策は大歓迎です!

4

1 に答える 1

0

別のスレッドで実行して、遅延を追加しようとしました。

任意の遅延を追加することは、スレッド間で同期する正しい方法ではありません。他のタスクが完了するまで待つ必要があります。

于 2012-07-24T14:20:16.793 に答える