10

私のC#アプリケーションは、ラップされたC++コードを計算に使用します。

C ++ヘッダー:

__declspec(dllexport) void SetVolume(BYTE* data, unsigned int width);

C ++ / CLIラッパー:

void SetVolume(array<Byte>^ data, UInt32 width) 
{
    cli::pin_ptr<BYTE> pdata = &data[0];
    pal->SetVolume(pdata, width); 
}

C#:

public startCalc()
{
    byte[] voxelArr = File.ReadAllBytes("Filtered.rec");
    palw.SetVolume(voxelArr, 490);
    //GC.KeepAlive(voxelArr); makes no sense
}

C ++SetVolume関数は、非同期計算を開始します。voxelArr管理側から参照されなくなり、ガベージコレクションされます。

voxelArrアンマネージコードがグローバル変数として宣言せずに動作を終了するまで、この参照のガベージコレクションを防ぐにはどうすればよいですか?配列のコピーを作成することは、実際には大量のデータがあるため、オプションではありません。内部でのアクティブな待機startCalc()も良くありません。

4

2 に答える 2

12

を使用してアレイを手動で固定し、GCがアレイを移動またはクリーンアップしないようにすることができます。GCHandle.Alloc(voxelArr,GCHandleType.Pinned)

次に、メソッドが完了したことがわかったらハンドルを解放する必要があります。これには、完了するために何らかの形式のコールバックが必要になります。

于 2013-02-06T17:50:33.873 に答える
1

現在のアプローチの別の代替案:

アレイを再度グローバルにし、最初に一度作成して固定し、必要なときにいつでも再利用することを検討してください。これらと同じ大きさのオブジェクトは気まぐれで作成しないでください、それらをプールしてください。より大きなサイズで再作成する必要がある場合にのみ、固定を解除して解放します

オブジェクトをグローバルプールに保存すると、ガベージコレクションが防止されます。厳密に言えば、これほど大きなオブジェクトを固定することを心配する必要はありませんが、一貫性を保つためにそうしてください

于 2013-02-06T18:15:50.667 に答える