0

I'm having problems while converting these structures to a byte array:

[StructLayout(LayoutKind.Sequential)]
/// <summary>
/// Packet structure, type 1 (SEND)
/// </summary>
internal struct PACKET_SEND
{
    /// <summary>
    /// Packet Type: 0 for notifications, 1 for status, 2 for login and auth.
    /// </summary>
    public Byte Type;
    /// <summary>
    /// Packet Key: select it from Packets class.
    /// </summary>
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = 61)]
    public char[] Key;
    /// <summary>
    /// Account Name.
    /// </summary>
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = 30)]
    public char[] AccountName;
    /// <summary>
    /// Account Status: 0 for offline, 1 for online, 2 for absent, 3 for busy, 4 for invisible.
    /// </summary>
    public Byte Status;
}

[StructLayout(LayoutKind.Sequential)]
/// <summary>
/// Packet structure, type 2 (RECV)
/// </summary>
internal struct PACKET_RECV
{
    /// <summary>
    /// Packet Type: 0 for notifications, 1 for status, 2 for login and auth.
    /// </summary>
    public Byte Type;
    /// <summary>
    /// Packet Key: select it from Packets class.
    /// </summary>
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = 61)]
    public char[] Key;
    /// <summary>
    /// Account Name.
    /// </summary>
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = 30)]
    public char[] AccountName;
}

Using these functions:

public static T ByteArrayToStructure<T>(byte[] data) where T : struct
    {
        GCHandle handle = GCHandle.Alloc(data, GCHandleType.Pinned);
        T stuff = (T)Marshal.PtrToStructure(handle.AddrOfPinnedObject(),
            typeof(T));
        handle.Free();
        return stuff;
    }

    public static byte[] StructToByteArray(object structure)
    {
        byte[] buffer = new byte[Marshal.SizeOf(structure)];
        GCHandle handle = GCHandle.Alloc(buffer, GCHandleType.Pinned);
        Marshal.StructureToPtr(structure, handle.AddrOfPinnedObject(), false);//HERE GETS EXCEPTION
        handle.Free();
        return buffer;
    }

I'm getting that exception while using "StructToByteArray" method:

Type could not be marshaled because the length of an embedded array instance does not match the declared length in the layout.

Ideas? Please, don't post only the solution but the explaination would be more appreciated :D. Greetings.

  • Sure that you did it right? I made a quick test and it worked for me. Can you show some more code? Btw my original code didn't show this ( http://stackoverflow.com/questions/8704161/c-sharp-array-within-a-struct/8704505#8704505 ) but i recommed to wrap the `Marshal` calls into `try ... finally`. – Felix K. Jan 02 '16 at 11:15

1 Answers1

0

See ...

Error : Type could not be marshaled because the length of an embedded array instance does not match the declared length in the layout

... and ...

Error on size of class

... maybe you don't initialize the array fields "Key" & "AccountName" or you don't initialize them correctly. The values always have to be 61 respectively 30 chars in size.

Community
  • 1
  • 1
Tom
  • 252
  • 1
  • 6
  • Trying that. I'm sure that the Key is **always** 61 char length but AccountName is variable. So going to "fill" and try. –  Jan 02 '16 at 11:28
  • @Ciavi Did you try to convert the array separate? Because this should not work, converting the hole struct is working. – Felix K. Jan 02 '16 at 11:38