2

我在 c# 中分配了一个大的 char[] 缓冲区,并希望将指向此数据的指针传递给 DLL 中未管理的 c 函数。

现在我认为要使其正常工作,必须修复 char 缓冲区,以便 GC 在函数工作时无法将其移动。

如果是这样,我会声明缓冲区 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 回答