2

C# に割り当てられた大きな char[] バッファーがあり、このデータへのポインターを DLL の umnanaged c 関数に渡したいと考えています。

これが機能するためには、関数の動作中にGCがシフトできないように、charバッファーを修正する必要があると思います。

もしそうなら、バッファをFIXEDと宣言し、UNSAFEブロック内でDLLを呼び出しますか??

fixed ( int* p = &bigbuffer )
{
    processbigbuffer(bigbuffer); 
}

私は検索しましたが、メモリが c# に属しているという問題と、これが DLL でどのように機能するかを強調している参照は多くありません。

ありがとう

4

2 に答える 2

2

を使用する必要はありませんfixed。ランタイムが自動的にそれを行います。したがって、C関数がある場合:

void ProcessBigBuffer(char* buffer);

マネージド プロトタイプは次のようになります。

[DllImport("foo.dll", CallingConvention=CallingConvention.Cdecl)]
static extern void ProcessBigBuffer([MarshalAs(UnmanagedType.LPArray)] char[] buffer);

呼び出しサイトは次のようになります。

char[] buffer = new char[bufferSize];
// initialize the buffer
// and then process it
ProcessBigBuffer(buffer);

以下も参照してください。

于 2013-05-17T14:49:09.703 に答える
1

はい、そうです。安全でないコードやデータをコピーすることなく、これを行うことができます。

var chars = new char[LARGE_AMOUNT];

var handle = GCHandle.Alloc(chars);
try
{ 
    processBigBuffer(/* this is an IntPtr -> */ handle.AddrOfPinnedObject, ... );
}
finally
{
    handle.Free();
}

私のOpenCLバインディングはこれをいたるところで使用しています (そして非常にパフォーマンスが高いです)。

于 2013-05-17T18:21:27.533 に答える