0

I need to convert struct to byte array with fixed bytes size. so the byte array with should be 12 bytes and order in array is CmdId -> code->Description

struct SendData 
{       
    public uint CmdID;          // 4 bytes       
    public uint code;           // 4 bytes        
    public string Description;  // 4 bytes
}

Can you help me please

Lucas Gras
  • 961
  • 1
  • 7
  • 22
Ashoka
  • 33
  • 1
  • 8

1 Answers1

0

You need to be aware that each character in a string is 2 bytes.

Given you have flagged this under sockets, I assume it's because you want to send this Packet over the wire?

You're going to need to encode your string of bytes into the packet using some other technique and if you want the memory in the packet to be sequential then you will need to define value types.

Here is a rudimentary example (note that each char is actually two bytes):

    [StructLayout(LayoutKind.Sequential, Pack = 1, CharSet = CharSet.Unicode)]
    struct SendData
    {
        public UInt32 CmdID;          // 4 bytes       
        public UInt32 code;           // 4 bytes        
        private char _description0;  // 2 bytes
        private char _description1;  // 2 bytes
        private char _description2;  // 2 bytes
        private char _description3;  // 2 bytes
        public string Description
        {
            get
            {
                return _description0.ToString() + _description1.ToString() + _description2.ToString() + _description3.ToString();
            }
            set
            {
                _description0 = value.ToCharArray(0, 4)[0];
                _description1 = value.ToCharArray(0, 4)[1];
                _description2 = value.ToCharArray(0, 4)[2];
                _description3 = value.ToCharArray(0, 4)[3];
            }
        }
        public byte[] ToByteArray()
        {
            int length = Marshal.SizeOf(this);
            byte[] byteArray = new byte[length];
            IntPtr pointer = Marshal.AllocHGlobal(length);
            Marshal.StructureToPtr(this, pointer, true);
            Marshal.Copy(pointer, byteArray, 0, length);
            Marshal.FreeHGlobal(pointer);
            return byteArray;
        }

    }

    static void Main(string[] args)
    {
        var sendData = new SendData();
        sendData.Description = "Hello World";

        var byteArray = sendData.ToByteArray();
        foreach (byte b in byteArray)
            Console.WriteLine($"Byte {b}");
    }

Producing the output:

Byte 0
Byte 0
Byte 0
Byte 0
Byte 0
Byte 0
Byte 0
Byte 0
Byte 72
Byte 0
Byte 101
Byte 0
Byte 108
Byte 0
Byte 108
Byte 0

Another option is to use an Unmanaged Type Directive on the string. But note that this means the string needs to be NULL terminated which results in 10 bytes in the string.

    [StructLayout(LayoutKind.Sequential, Pack = 1, CharSet = CharSet.Unicode)]
    struct SendData
    {
        public UInt32 CmdID;          // 4 bytes       
        public UInt32 code;           // 4 bytes        
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 5)]
        private string _description;  // 10 bytes

        public string Description
        {
            get
            {
                return _description;
            }
            set
            {
                _description = value.Substring(0, 4);

            }
        }
Rowan Smith
  • 1,815
  • 15
  • 29