简体   繁体   中英

How can I marshal a struct containing strings of variable size?

I'm sending stuff over a TCP connection from the client to my server in a packet ( MemoryStream ), and on the server end I want to re-create the original object by using the Marshal. I'm using the following code to marshal stuff into the packets:

    public void Write<T>(T value) where T : struct
    {
        byte[] buffer = new byte[Marshal.SizeOf(typeof(T))];

        // Fill the buffer with our stuff please!
        fixed (byte* b = buffer)
            Marshal.StructureToPtr(value, new IntPtr(b), false);

        // And write it to the MemoryStream. Kthx!
        Write(buffer, 0, buffer.Length);
    }

When I'm done writing stuff to the packet I call ToArray() on it and send it over to the server. The server will then receive a byte array with all the data in it.

And this works fine for all primitive types, but it doesn't work too well for my custom structs. Consider the following struct I'm using:

[StructLayout(LayoutKind.Sequential)]
public struct HotspotUpdate
{
    public string LeaderHash { get; set; }
    public string OurName { get; set; }
    public CommandSide Side { get; set; }
    public CommandType Type { get; set; }
    public Vector3 Location { get; set; }
}

I usually make these structs work by specifying the Size in the StructLayout attribute. However, now I have two strings in there of varying size, and I can't for the life of me figure out how I can get the Marshal to grab a packet (which is a byte array) and have it marshal it back to the above struct since I can't specify it as an LPStr and set its size - it will vary.

So whenever I do attempt this, the marshal will yell at me, saying:

Type 'HotspotUpdate' cannot be marshaled as an unmanaged structure; no meaningful size or offset can be computed.

Is there any way I can make this work, or will I have to resort to just sending over strings a byte arrays and working them out on the server end?

The CLR demands that struct members are located at fixed offsets. Therefore, there are no variably-sized members.

Probably, you should use a higher level of abstraction anyway. Use protocol buffers to automate all your serialization needs in a convenient and robust way.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM