C#unmovable动态分配的数组

时间:2013-09-11 07:30:55

标签: c# arrays garbage-collection

我在C#中创建一个调用DLL(由DAQ卡供应商提供)的数据采集应用程序,它要求我在该DLL中注册我的I / O缓冲区。我有一个写入线程,用信号样本填充缓冲区。我看到一种奇怪的行为,一段时间后输出信号变成了噪音,我怀疑是因为GC已经将缓冲区移到了某处,所以DLL中的代码有一个指向错误地址的指针并将垃圾输出到DAC。

1)如何检查我是否正确(阵列已被移动)?

2)如果是这样,如何使数组不可移动? MSDN上的Fixed Size Buffers页面说我可以创建一个固定大小的缓冲区,但是我需要它动态地进行定位(因此可以在采集开始之前进行调整)。

2 个答案:

答案 0 :(得分:2)

您使用:

int[] myarray = new int[1000];

GCHandle handle = GCHandle.Alloc(myarray, GCHandleType.Pinned);

记得

handle.Free();

最后。因此,如果DLL方法生成一个线程并立即返回,通常最好将句柄放在类的字段中,而不是作为局部变量。

请注意,如果您需要在函数调用时生成一个数组,那么您不需要这样做。例如:

int[] myarray = new int[1000];
MyPInvokeMethod(myarray);

对于MyPInvokeMethod的整个生命周期,数组将自动固定。

答案 1 :(得分:1)

int[] data = new int[size];
GCHandle h = GCHandle Alloc(data, GCHandleType.Pinned);
IntPtr ptr = h.AddrOfPinnedObject();

// ptr points to fixed memory which is not moved by GC 
// and can be accessed by unmanaged code

// ...

h.Free();     // now array can be moved