【发布时间】:2019-06-27 07:48:31
【问题描述】:
我已将结构数组从 C#(托管代码)传递到 C(非托管代码)。 struct的内存是在C#端分配的。该数组以 C 代码填充。我的代码是多线程的。数组的填充由一个线程完成,另一个线程从结构数组中读取已经填充的项目。但是在第一个线程退出之前,我无法从第二个线程读取数据,但是内存是由两个线程共享的。
示例代码
C#结构
public struct Data
{
public IntPtr str;
[MarshalAs(UnmanagedType.I4)]
public int id;
}
在C#端分配struct数组的内存
GCHandle[] handles = new GCHandle[10];
for (int i = 0; i < 10; i++)
{
_data[i] = new Data();
byte[] bd = new byte[100];
handles[i] = GCHandle.Alloc(bd, GCHandleType.Pinned);
data[i].str = handles[i].AddrOfPinnedObject();
}
第一个线程将此结构数组_data传递给非托管代码(C代码)以使用func填充
void func([In,Out] Data[] _data);
第二个线程开始读取填充的结构数据,但第一个线程仍在填充剩余索引的数据。在这种情况下,数据可用于
_data[0].str
但
_data[0].id
显示为 0,但在 C 端显示正确的填充值,即 5。请帮助解释为什么 struct member int id 的数据为 0。正确的值仅在第一个线程结束后出现。但是由于内存是共享的,它必须在被非托管代码填充后立即可用。
我们将不胜感激。
我希望即使线程 1 没有结束线程 2 也必须能够获取已在非托管代码中填充的索引值。
【问题讨论】:
标签: c# marshalling unmanaged