'Convert Nested Struct to Byte Array

The code

using System;
using System.Runtime.InteropServices;

class Program {

   [StructLayout(LayoutKind.Sequential, Pack = 1)]
   public struct Inner{
      public byte firstByte;
      public byte secondByte;
    };
   [StructLayout(LayoutKind.Sequential, Pack = 1)]
   public struct Outer{
      public short firstShort;
      public Inner[] inners;
    };

  public static byte[] ConvertStructToByteArray(object obj)
  {
      int len = Marshal.SizeOf(obj);
      byte[] arr = new byte[len];
      IntPtr ptr = Marshal.AllocHGlobal(len);
      Marshal.StructureToPtr(obj, ptr, true);
      Marshal.Copy(ptr, arr, 0, len);
      Marshal.FreeHGlobal(ptr);
      return arr;
  }

  
  public static void Main (string[] args) {
    Console.WriteLine ("Hello World");
    var inner = new Inner();
    inner.firstByte = 0x00;
    inner.secondByte = 0x01;
    var outer = new Outer();
    outer.firstShort = 0x0000;
    outer.inners = new Inner[]{inner};
    var byteArray = ConvertStructToByteArray(outer);
  }
}

is supposed to convert the outer struct instance into a byte array, but instead throws

Unhandled exception. System.ArgumentException: Type 'Program+Outer' cannot be marshaled as an unmanaged structure; no meaningful size or offset can be computed.
   at System.Runtime.InteropServices.Marshal.SizeOfHelper(Type t, Boolean throwIfNotMarshalable)
   at System.Runtime.InteropServices.Marshal.SizeOf(Object structure)
   at Program.ConvertStructToByteArray(Object obj) in /home/runner/ZigzagGracefulDatum/main.cs:line 23
   at Program.Main(String[] args) in /home/runner/ZigzagGracefulDatum/main.cs:line 47

Why is there a problem with the size evaluation? How can it be fixed? Is there a better solution?



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source