4

I was trying to use a struct to parse socket data when implement a UDP based protocol. And I searched and I can use these 2 functions to convert between byte[] and struct:

 byte[] StructToBytes(object structObj)
    {
        int size = Marshal.SizeOf(structObj);
        IntPtr buffer = Marshal.AllocHGlobal(size);
        try
        {
            Marshal.StructureToPtr(structObj, buffer, false);
            byte[] bytes = new byte[size];
            Marshal.Copy(buffer, bytes, 0, size);
            return bytes;
        }
        finally
        {
            Marshal.FreeHGlobal(buffer);
        }

    }

    static object BytesToStruct(byte[] bytes, Type strcutType, int offset = 0)
    {
        int size = Marshal.SizeOf(strcutType);
        IntPtr buffer = Marshal.AllocHGlobal(size);
        try
        {
            Marshal.Copy(bytes, offset, buffer, size);
            return Marshal.PtrToStructure(buffer, strcutType);
        }
        finally
        {
            Marshal.FreeHGlobal(buffer);
        }
    }

Then I had this problem:

//I defined a simple struct with an ushort member
    [StructLayout(LayoutKind.Sequential, Pack = 2)]
    struct S
    {
        public ushort a;
    }

    //Then I define a byte[]
    byte[] bArr;
    bArr[0] = 0;
    bArr[1] = 1;

    //Convert to struct
    S s = (S)BytesToStruct(bArr, typeof(S));
    //Then s.a = 0x0100 not 0x0001

And struct to byte[] is just the same. The 2 bytes of ushort are reversed. How do I solve this problem?

3 Answers 3

2

Most processors these days use Little-Endian byte ordering (Least significant byte comes first). Network byte ordering is traditional Big-Endian, so you usually need to mirror the byte order. You can check the endianness of the system with System.BitConverter.IsLittleEndian

The .Net equivalent of ntohs() Frank mentioned is located (oddly) at System.Net.IPAddress.NetworkToHostOrder()

You could also write your own mechanism to read the bytes in the correct order directly, using bit shifting and logical OR.

Sign up to request clarification or add additional context in comments.

Comments

1

There's a difference between network byte order and host byte order.

Typically, in C at least, you use ntohl(), ntohs() and friends to convert network byte order to your host order when reading from a socket.

Comments

1

The problem is to do with the endianness of short on your system. Have a look at this question about endianness, which may provide some pointers (pun unintentional).

Also, I would suggest making BytesToStruct generic in the type of the struct:

static S BytesToStruct<S>(byte[] bytes, int offset = 0)

so it could be called with

BytesToStruct<S>(bArr)

rather than as at present

(S)BytesToStruct(bArr, typeof(S))

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.