我已经通过从C#(管理代码)到C(非托管代码)一个结构阵列。结构的内存在C#中端分配。该阵列中的C代码填充。我的代码是多线程的。阵列的填充是由一个线程完成,另一个线程读取从结构阵列已经居住项目。但我无法读取从第二个线程的数据,直到不过,内存是由双方共享的第一个线程退出。
示例代码
C#结构
public struct Data
{
public IntPtr str;
[MarshalAs(UnmanagedType.I4)]
public int id;
}
分配结构阵列的存储在C#侧
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,请帮忙为什么结构成员INT ID数据即将0的正确值只来自第一线后结束。但是由于存储器是共享的,必须因为它是由非托管代码填写尽快上市。
任何帮助将得到高度赞赏。
我想了即使线程1不结束线程2必须能够获取其已填补在非托管代码率的值。
因为传递一个管理的阵列到非托管代码,CLR将复制阵列到另一个存储器块,然后再传递到非托管函数。非托管函数完成后,CLR将元帅内存放回管理的阵列,那么你得到的结果。
一种解决方案是直接与不安全代码使用数组地址。
extern void func(Data* data);
fixed(Data* p = _data)
{
func(p);
}
如果你不喜欢不安全代码,由于结构阵列的存储器是连续的,则可以通过第一元件的参考。但我不知道是否足够安全。
extern void func(ref Data data);
func(ref _data[0]);