C#怎么实现union类型啊 本帖最后由 maomiaomi 于 2011-03-31 11:31:00 编辑 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 虽然我没去验证,但你要实现union的效果,起码要定义b的FieldOffset为0吧? 定义b的FieldOffset为0会报错,所以定义为8了,但是如果内存是像c++那样构造的话,8和0是一样的 怎么会一样呢union testunion { double a[3]; double b; };这样定义的话, a[0]的内存偏移和b的内存偏移都是0如果.net不允许定义两个字段的偏移相同,那可能还真没办法了 两个字段可以相同 ,关键是有了对象double a[3];就会报错了[FieldOffset(0)]float f1;[FieldOffset(32)]float f2;[FieldOffset(0)]double d;没问题再加条[FieldOffset(0),MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)]public double[] a;就有问题了建议用c/c++的dll 哦,忽然想起来了,你这个问题实际上是这样你定义的public double[] a事实上是一个对象,也就是说struct里对应的只有一个指针,结果自然不对 double[] a是一个引用, 推荐你[FieldOffset(0)]float f1;[FieldOffset(0)]float f2;[FieldOffset(0)]double d;就这样定义如果定义成数组,那就变成对象的引用了 谢谢楼上各位的回复[FieldOffset(0)]float f1;[FieldOffset(0)]float f2;[FieldOffset(0)]double d;这个确实能解决问题,可是我在网上查到的好多资料都是 [FieldOffset(0),MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)] public double[] a;这样解决的不必纠结于对齐没对齐union testunion { double a[3]; double c; double b; };testunion aaaa;aaaa.a[0]=100;aaaa.a[1]=2;cout<<sizeof(aaaa)<<" "<<aaaa.b<<endl;这样的话b就和c#里面的b一样了 汗楼上的错了应该是这样union testunion { double a[3]; double c; double b[2]; };testunion aaaa;aaaa.a[0]=100;aaaa.a[1]=2;cout<<sizeof(aaaa)<<" "<<aaaa.b[1]<<endl;这个b[1]和c#里面的b偏移量是相同的 现在的关键问题不在于内存对齐而是在C#里声明一个double[]等于是声明了一个Array类的对象,这样结构体里保存的就是对象的引用,虽然Marshal.SizeOf返回仍然是24,但那是CLR将ManagedType转化为Unmanaged以后的结果,一旦你再声明一个Offset是0的字段,就会因为内存重叠覆盖掉引用类型而出错——无法加载,更谈不上ManagedType转化Unmanaged。要么罗列出值类型字段,不用Array要么想办法以unsafe代码解决 [StructLayout(LayoutKind.Explicit, CharSet = CharSet.Auto)] struct testunion { [FieldOffset(0),MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)] public double[] a; [FieldOffset(8)] public double b; }可是实际上调用dll的时候,a[1]和b的值是相等的莫非是接受数据的时候对它进行了转换? .net关于没有为任何调用堆栈框架加载任何符号的问题 求怎么做在程序启动后,任务栏出现一个图标 C# 智能客户端应用程序开发 操作手册问题 复制datarow C# chart 控件如何改变大小 java读取C#写入的二进制文件出错 请问如何判断客户端是否支持XSL转换? 请问如何在MessageBox.Show("http://www.163.net")弹出URL信息时带连接? 求助!C#使用Replace不能正常去除换行符 C# 小虾求助Forms身份验证问题 关于C#串口通信连续发送命令的问题
union testunion
{
double a[3];
double b;
};这样定义的话, a[0]的内存偏移和b的内存偏移都是0
如果.net不允许定义两个字段的偏移相同,那可能还真没办法了
float f1;
[FieldOffset(32)]
float f2;
[FieldOffset(0)]
double d;
没问题再加条
[FieldOffset(0),MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)]
public double[] a;
就有问题了建议用c/c++的dll
你定义的
public double[] a
事实上是一个对象,也就是说struct里对应的只有一个指针,结果自然不对
是一个引用,
[FieldOffset(0)]
float f1;
[FieldOffset(0)]
float f2;
[FieldOffset(0)]
double d;就这样定义
如果定义成数组,那就变成对象的引用了
float f1;
[FieldOffset(0)]
float f2;
[FieldOffset(0)]
double d;这个确实能解决问题,
可是我在网上查到的好多资料都是 [FieldOffset(0),MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)]
public double[] a;这样解决的
不必纠结于对齐没对齐union testunion
{
double a[3];
double c;
double b;
};
testunion aaaa;
aaaa.a[0]=100;
aaaa.a[1]=2;
cout<<sizeof(aaaa)<<" "<<aaaa.b<<endl;这样的话b就和c#里面的b一样了
{
double a[3];
double c;
double b[2];
};
testunion aaaa;
aaaa.a[0]=100;
aaaa.a[1]=2;
cout<<sizeof(aaaa)<<" "<<aaaa.b[1]<<endl;这个b[1]和c#里面的b偏移量是相同的
而是在C#里声明一个double[]等于是声明了一个Array类的对象,这样结构体里保存的就是对象的引用,虽然Marshal.SizeOf返回仍然是24,但那是CLR将ManagedType转化为Unmanaged以后的结果,一旦你再声明一个Offset是0的字段,就会因为内存重叠覆盖掉引用类型而出错——无法加载,更谈不上ManagedType转化Unmanaged。要么罗列出值类型字段,不用Array
要么想办法以unsafe代码解决
[StructLayout(LayoutKind.Explicit, CharSet = CharSet.Auto)]
struct testunion
{
[FieldOffset(0),MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)]
public double[] a;
[FieldOffset(8)]
public double b;
}可是实际上调用dll的时候,a[1]和b的值是相等的
莫非是接受数据的时候对它进行了转换?