Casting explicitly-laid out structures

c#, casting, struct, type-conversion

Solution

Two options here:

No unsafe code, but explicit structure layout

(Note that although this isn't unsafe as far as the C# compiler is concerned, some frameworks may still disallow it - see Marc Gravell's comment.)

You could use a union type, which is just another struct with two fields, both set explicitly to the same location. Here's a complete example using your structures:

using System;
using System.Runtime.InteropServices;

[StructLayout(LayoutKind.Explicit)]
public struct Chapter4Time
{
    [FieldOffset(0)]
    public UInt16 Unused;
    [FieldOffset(2)]
    public UInt16 TimeHigh;
    [FieldOffset(4)]
    public UInt16 TimeLow;
    [FieldOffset(6)]
    public UInt16 MicroSeconds;
}

[StructLayout(LayoutKind.Explicit)]
public struct IEEE_1588Time
{
    [FieldOffset(0)]
    public UInt32 NanoSeconds;
    [FieldOffset(4)]
    public UInt32 Seconds;
}

[StructLayout(LayoutKind.Explicit)]
public struct TimeUnion
{
    [FieldOffset(0)]
    public Chapter4Time Chapter4Time;
    [FieldOffset(0)]
    public IEEE_1588Time IEEE_1588Time;
}

class Test
{    
    static void Main()
    {
        var ch4 = new Chapter4Time { TimeLow = 100, MicroSeconds = 50 };
        var union = new TimeUnion { Chapter4Time = ch4 };
        Console.WriteLine(union.IEEE_1588Time.Seconds);
    }
}

Unsafe code, casting pointers

An alternative to the union type if you can use unsafe code is to cast a pointer of type `Chapter4Time*` to `IEEE_1588Time*`:

class Test
{    
    unsafe static void Main()
    {
        var ch4 = new Chapter4Time { TimeLow = 100, MicroSeconds = 50 };
        var ieee1588 = *((IEEE_1588Time*) &ch4);
        Console.WriteLine(ieee1588.Seconds);
    }
}

Personally I'd avoid doing any of this if at all possible, but if you *really, really want to do it, these are probably the simplest approaches.

Problem

Let's say I have this structure, ``` [StructLayout(LayoutKind.Explicit)] public struct Chapter4Time { [FieldOffset(0)] public UInt16 Unused; [FieldOffset(2)] public UInt16 TimeHigh; [FieldOffset(4)] public UInt16 TimeLow; [FieldOffset(6)] public UInt16 MicroSeconds; } ``` and this structure. ``` [StructLayout(LayoutKind.Explicit)] public struct IEEE_1588Time { [FieldOffset(0)] public UInt32 NanoSeconds; [FieldOffset(4)] public UInt32 Seconds; } ``` How would I convert from one structure to the other?

Original source

Related problems