dev*_*ium 9 .net c# c++ struct unions
关于具有LayoutKind.Explicit
属性集的结构,我有一个小问题.struct
正如您所见,我声明了fieldTotal
64位,fieldFirst
即前32个字节和fieldSecond
最后32个字节.既设置完毕后fieldfirst
,并fieldSecond
到Int32.MaxValue
,我希望fieldTotal
是Int64.MaxValue
,实际上不会发生.为什么是这样?我知道C#并不真正支持C++联合,也许它只会在插入时很好地读取值,但是当我们尝试自己设置这些值时它根本就不能很好地处理它?
[StructLayout(LayoutKind.Explicit)]
struct STRUCT {
[FieldOffset(0)]
public Int64 fieldTotal;
[FieldOffset(0)]
public Int32 fieldFirst;
[FieldOffset(32)]
public Int32 fieldSecond;
}
STRUCT str = new STRUCT();
str.fieldFirst = Int32.MaxValue;
str.fieldSecond = Int32.MaxValue;
Console.WriteLine(str.fieldTotal); // <----- I'd expect both these values
Console.WriteLine(Int64.MaxValue); // <----- to be the same.
Console.ReadKey();
Run Code Online (Sandbox Code Playgroud)
Ben*_*n M 10
原因是FieldOffsetAttribute将多个字节作为参数 - 而不是位数.这按预期工作:
[StructLayout(LayoutKind.Explicit)]
struct STRUCT
{
[FieldOffset(0)]
public Int64 fieldTotal;
[FieldOffset(0)]
public Int32 fieldFirst;
[FieldOffset(4)]
public Int32 fieldSecond;
}
Run Code Online (Sandbox Code Playgroud)
如果Int32.MaxValue和Int64.MaxValue应该提供答案,请查看十六进制值.
关键是最重要的一点.对于正整数,最高有效位仅设置为负数.所以Int32的最大值是0,后跟整个1s的系列.顺序并不重要,只需要至少有一个0位.Int64.MaxValue也是如此.
现在考虑一个联盟应该如何运作.它基本上会将值的位置彼此相邻.所以现在你有一组64位长度,包含两个0位值.每个Int32.MaxValue实例一个.这不能等于Int64.MaxValue,因为它只能包含一个0位.
奇怪的是,如果将fieldSecond设置为Int32.MinValue,您可能会得到您正在寻找的行为.
编辑错过了你需要使它成为FieldOffset(4).