运行环境: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++结构体的对齐方式,结果还是**结构体数据被刷掉**。