问题描述
- 如何解决C#向C++DLL传递 struct数组时产生的数据丢失问题?
-
运行环境:win8.1+vs2010目的:将C#中的结构体数组传到C++的动态链接库中
代码:
//DLL中的接口,C++ struct Target { int ID; double PosX double PosY; float Aangle; long EncoderValue; }; class Backstage { EXTERN_C BACKSTAGE_API int WINAPI Allocater_AddNewTargets(Target *targets,int num); }
//使用DLL的c#代码 [StructLayoutAttribute(LayoutKind.Sequential, Pack = 1)] public struct Target { public int ID; public double PosX; public double PosY; public float Aangle; public long EncoderValue; }; private void button1_Click(object sender, RoutedEventArgs e) { Target[] targets = new Target[4]; targets[0].Aangle = 12.1F; targets[0].EncoderValue = 0; targets[0].ID = 10; targets[0].PosX = 12.4; targets[0].PosY = 123.22; unsafe { fixed (Target* p = targets) { Backstage.Allocater_AddNewTargets(p, targets.Length); } } }
问题描述:当调用函数时马上出现结构体数据被刷掉的情况。断点在进入Allocater_AddNewTargets的前一句代码,结构体中的数据还是正确的。断点在Allocater_AddNewTargets中的第一句代码,发现结构体的数据已经被刷掉了。
注意:结构体地址被正确传送,甚至结构体内的每一个变量的地址也正确尝试:
1、在C#中用IntPtr开辟非托管内存块储存结构体,并用IntPtr作为参数,还是一样的情况,**结构体数据被刷掉**。
2、把C#结构体的[StructLayoutAttribute(LayoutKind.Sequential, Pack = 1)]特性去掉,**结构体数据正确,但出现内存边界对齐问题。**C++的结构体是4字符对齐,C#的结构体是8字符对齐。
3、把C#结构体的[StructLayoutAttribute(LayoutKind.Sequential, Pack = 1)]特性去掉,改为在C++中用#pragma pack(1)改变C++结构体的对齐方式,结果还是**结构体数据被刷掉**。
解决方案
C++的long还是32位的,C#是64位的。
解决方案二:
结构体中成员定义写成类似这样的
struct XXX
{
[MarshalAs(UnmanagedType.I4)]
public int index;
...
}
时间: 2024-10-18 13:06:08