views:

104

answers:

1

his question is about converting between a struct and a byte array. Many solutions are based around GCHandle.Alloc() and Marshal.StructureToPtr(). The problem is these calls generate garbage. For example, under Windows CE 6 R3 about 400 bytes of garbarge is made with a small structure. If the code below could be made to work the solution could be considered cleaner. It appears the sizeof() happens too late in the compile to work.

public struct Data
{
    public double a;
    public int b;
    public double c;
}

[StructLayout(LayoutKind.Explicit)]
public unsafe struct DataWrapper
{
    private static readonly int val = sizeof(Data);

    [FieldOffset(0)]
    public fixed byte Arr[val]; // "fixed" is to embed array instead of ref

    [FieldOffset(0)]
    public Data; // based on a C++ union
}
+1  A: 

You can in fact use the constant value 1 as the size of the fixed array in DataWrapper. There is no bounds checking when accessing an unsafe fixed array nor is there any mechanism to request its length at runtime. The presence of the Data member at offset 0 is enough to ensure that you can actually read and write sizeof(Data) bytes to/from DataWrapper.Arr.

With that said, a more straight forward solution would be to cast a Data* pointer to byte* as follows:

unsafe {
    Data d = new Data();
    d.a = 125.5;
    d.b = 0x7FEEDDEE;
    d.c = 130.0;
    byte* bytes = (byte*)&d;
    for (int i = 0; i < sizeof(Data); i++) {
      Console.WriteLine(i + ": " + bytes[i]);
    }
}
Nick Guerrera
My goal here is to flatten a struct into a byte array to write into shared memory. Then, be able to retrieve the byte array and convert it back into a struct. A union or the unsafe code shown would accomplish this. One issue is the solutions above won't work with generics. A colleague pointed me to the following websitehttp://www.codeproject.com/KB/cs/ReadingStructuresEmit.aspxThis solution automatically emits IL code to do the conversion for a type T. Somehow it feels risky, but it could be my lack of understanding.