0

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

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

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

4

2 回答 2

2

你用:

int[] myarray = new int[1000];

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

记得

handle.Free();

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

请注意,如果您需要在函数调用期间使数组处于活动状态,则无需执行此操作。例如:

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

在阵列的整个生命周期中,MyPInvokeMethod将自动固定。

于 2013-09-11T07:33:29.913 回答
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
于 2013-09-11T07:35:28.077 回答