我有一个看起来像这样的结构:
[StructLayout(LayoutKind.Sequential)]
public struct in_addr {
public Anonymous1 S_un;
[StructLayoutAttribute(LayoutKind.Explicit)]
public struct Anonymous1 {
[FieldOffsetAttribute(0)]
public Anonymous2 S_un_b;
[FieldOffsetAttribute(0)]
public Anonymous3 S_un_w;
[FieldOffsetAttribute(0)]
public uint S_addr;
}
[StructLayoutAttribute(LayoutKind.Sequential)]
public struct Anonymous2 {
public byte s_b1;
public byte s_b2;
public byte s_b3;
public byte s_b4;
}
[StructLayoutAttribute(LayoutKind.Sequential)]
public struct Anonymous3 {
public ushort s_w1;
public ushort s_w2;
}
public in_addr(byte[] address) {
S_un.S_addr = (uint)BitConverter.ToInt32(address, 0);
S_un.S_un_b.s_b1 = address[0];
S_un.S_un_b.s_b2 = address[1];
S_un.S_un_b.s_b3 = address[2];
S_un.S_un_b.s_b4 = address[3];
S_un.S_un_w.s_w1 = 0;
S_un.S_un_w.s_w2 = 0;
}
}
当我尝试创建此结构的新实例时,每个字节字段都设置为0。
in_addr temp = new in_addr(bytes);
我已经逐步完成了struct的构造函数,并验证了字节确实被分配给了字段。但是当我走出构造函数并检查temp
的值时,一切都是0。
造成这种情况的原因是什么?
答案 0 :(得分:5)
由于这些原因:
S_un.S_un_w.s_w1 = 0;
S_un.S_un_w.s_w2 = 0;
它们通过
映射到您的4个字节[FieldOffsetAttribute(0)]
public Anonymous2 S_un_b;
[FieldOffsetAttribute(0)]
public Anonymous3 S_un_w;
答案 1 :(得分:3)
我无法重现这一点;你的代码适合我。我正在使用Mono,但我非常怀疑这是Microsoft C#编译器中的一个错误,你更有可能在其他地方出错。
答案 2 :(得分:1)
我刚刚使用C#在VisualStudio 2008中对此进行了测试,得到了预期的输出(1,2)。
尝试发布您遇到问题的实际示例代码。
编辑这就是为什么示例代码可能不好;)
您的问题出在StructLayout.Explicit
Anonymous1
上。是否有特殊原因
当我将其更改为Sequential
并删除属性时,它对我来说很好。
编辑2 (已删除)
编辑3
您的问题在于构造函数中的赋值。不知道我是怎么错过这个的。您不需要设置所有这些变量,因为您的FieldOffset
属性会将它们全部存储在同一位置。结构本身只占用4个字节的内存(理论上,无论如何)。无论您是通过int
,byte
还是两个short
访问它们,它们都会转到同一个地方。因此,前两组分配(int
和byte
)是冗余的,最后一组(short
将它们设置为0)清除你刚刚做了什么。
不幸的是C#编译器不知道这一点,所以我确定你添加了最后一个赋值,因为它抱怨结构没有完全分配。首先为short
和int
添加虚拟分配,然后从数组中明确指定byte
。
答案 3 :(得分:0)
如果您使用的是C#3.0,请尝试以下操作:
MyStruct ms = new MyStruct
{
MyByte = 1,
MyNestedStruct.NestedStryctByte = 2
}
这应该有效,并且可以减轻在结构中使用构造函数的需要。如果无法直接初始化NestedStructByte,请先创建它:
MyStruct ms = new MyStruct
{
MyByte = 1,
MyNestedStruct = new MyStruct.NestedStruct
{
NestedStryctByte = 2
}
}
答案 4 :(得分:0)
我测试了你的代码 - 一切都很好。
public struct MyStruct
{
public byte MyByte;
public NestedStruct MyNestedStruct;
public struct NestedStruct
{
public byte NestedStructByte;
}
public MyStruct(byte[] bytes)
{
MyByte = bytes[0];
MyNestedStruct.NestedStructByte = bytes[1];
}
}
class Program
{
static void Main(string[] args)
{
MyStruct ms = new MyStruct(new byte[] { 1, 2 });
//ms.MyByte; // 0, but should be 1
//ms.MyNestedStruct.NestedStructByte; // 0, but should be 2
}
}