Reputation: 36239
I have a struct that looks something like this:
[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;
}
}
When I try to create a new instance of this struct, every byte field is set to 0.
in_addr temp = new in_addr(bytes);
I've stepped through the struct's constructor and verified that the bytes are indeed getting assigned to the fields. But when I step out of the constructor and check the value of temp
, everything is 0.
What's causing this?
Upvotes: 0
Views: 281
Reputation: 185583
I just tested this in VisualStudio 2008 using C# and got the expected output (1, 2).
Try posting the actual example code that you're having an issue with.
EDIT This is why example code can be bad ;)
Your issue was with the StructLayout.Explicit
on Anonymous1
. Is there a particular reason that
When I changed it to Sequential
and removed the attributes, it worked fine for me.
EDIT 2 (Deleted)
EDIT 3
Your issue is with the assignment in the constructor. Not sure how I missed this. You don't need to set all of those variables, because your FieldOffset
attribute makes them all stored in the same location. The struct itself is only occupying 4 bytes of memory (in theory, anyway). Whether you're accessing it via the int
, the byte
s, or the two short
s, they all go to the same place. As a result, your first two sets of assignments (to the int
and to the byte
s) are redundant, and the last set (to the short
s setting them to 0) clears out what you just did.
Unfortunately the C# compiler doesn't know this, so I'm sure you added the last assignment because it complained about the struct not being fully assigned. Add the dummy assignments first for the short
s and the int
, then assign the byte
s explicitly from the array.
Upvotes: 1
Reputation: 3596
Because of these lines:
S_un.S_un_w.s_w1 = 0;
S_un.S_un_w.s_w2 = 0;
They are mapped to your 4 bytes via
[FieldOffsetAttribute(0)]
public Anonymous2 S_un_b;
[FieldOffsetAttribute(0)]
public Anonymous3 S_un_w;
Upvotes: 5
Reputation: 801
I tested your code - everything is OK.
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
}
}
Upvotes: 0
Reputation: 32950
If you are using C# 3.0, just try the following:
MyStruct ms = new MyStruct
{
MyByte = 1,
MyNestedStruct.NestedStryctByte = 2
}
That should work, and would alleviate the need to have a constructor in your struct. If you can't directly initialize the NestedStructByte, create it first:
MyStruct ms = new MyStruct
{
MyByte = 1,
MyNestedStruct = new MyStruct.NestedStruct
{
NestedStryctByte = 2
}
}
Upvotes: 0
Reputation: 545488
I can't reproduce this; your code works for me. I’m using Mono but I very much doubt that this is a bug in the Microsoft C# compiler, it's more likely that you've got an error elsewhere.
Upvotes: 3