将指向托管代码中分配的内存的指针传递给非托管代码

时间:2013-05-17 14:32:10

标签: c#

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

现在我觉得为了工作,char缓冲区必须是固定的,以便GC在函数工作时无法移动它。

如果是这样,我会声明缓冲区FIXED并调用DLL和UNSAFE块吗?

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

我搜索过但没有多少引用突出显示内存属于c#的问题以及它如何在DLL中起作用。

由于

2 个答案:

答案 0 :(得分: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);

另见:

答案 1 :(得分:1)

是的,的确如此。您可以在没有不安全代码且无需复制数据的情况下执行此操作。

var chars = new char[LARGE_AMOUNT];

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

我的OpenCL绑定在整个地方使用它(并且非常高效)。