I know this question has been asked many times before, and I've tried to read through all the previous questions without much luck.
I am trying to convert the following C++ struct to C#, for use with socket communication.
enum class packet_type
{
read_mem,
get_base_addr,
get_pid,
completed
};
struct copy_mem
{
unsigned int dest_process_id;
unsigned long long dest_address;
unsigned int src_process_id;
unsigned long long src_address;
unsigned int size;
};
struct get_base_addr
{
unsigned int process_id;
};
struct get_pid
{
size_t len;
wchar_t name[256];
};
struct completed
{
unsigned long long result;
};
struct PacketHeader
{
//uint32_t magic;
packet_type type;
};
struct Packet
{
PacketHeader header;
union
{
copy_mem copy_memory;
get_base_addr get_base_address;
get_pid get_pid;
completed completed;
} data;
};
And this is my current C# implementation
public enum PacketType
{
read_mem = 0,
get_base_addr = 1,
get_pid = 2,
completed = 3
}
[StructLayout(LayoutKind.Sequential)]
public struct PacketHeader
{
public PacketType type;
}
[StructLayout(LayoutKind.Sequential)]
public struct get_base_addr
{
uint process_id;
};
[StructLayout(LayoutKind.Sequential)]
public struct get_pid
{
public ulong len;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
public string name;
}
[StructLayout(LayoutKind.Sequential)]
public struct copy_mem
{
public uint dest_process_id;
public ulong dest_address;
public uint src_process_id;
public ulong src_address;
public uint size;
}
[StructLayout(LayoutKind.Sequential)]
public struct completed
{
public ulong result;
};
[StructLayout(LayoutKind.Explicit, Pack = 0, CharSet = CharSet.Unicode)]
public struct Packet
{
[FieldOffset(0)] //
public PacketHeader header;
[FieldOffset(4)]
public copy_mem CopyMem; //28
[FieldOffset(32)]
public get_base_addr GetBaseAddress;
[FieldOffset(36)]
public get_pid GetPid;
[FieldOffset(300)]
public completed Completed;
}
I am then using this method to convert the struct to a byte array for the socket transmission:
public static byte[] RawSerialize(T item)
{
int rawSize = Marshal.SizeOf(typeof(T));
IntPtr buffer = Marshal.AllocHGlobal(rawSize);
var a = Marshal.SizeOf(item);
var b = Marshal.SizeOf(buffer);
Marshal.StructureToPtr(item, buffer, false);
byte[] rawData = new byte[rawSize];
Marshal.Copy(buffer, rawData, 0, rawSize);
Marshal.FreeHGlobal(buffer);
return rawData;
}
The issue is that var a = Marshal.SizeOf(item);
reports a size of 312
, but the actual struct should be 528
bytes when I do sizeof(Packet)
in C++