Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Convert byte array to object

Tags:

c#

Is there a way in C# to convert a plain byte array to an object?

e.g given this class:

class Data
{
    public int _int1;
    public int _int2;
    public short _short1;
    public long _long1;
}

I want to basically be able to do something like this:

var bytes = new byte[] { 1, 0, 0, 0, 2, 0, 0, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0 };
var obj = (Data)bytes;
like image 972
Mark Avatar asked Nov 29 '25 05:11

Mark


1 Answers

You could try marshalling:

Declare the layout of your class as Sequential (and note that you will need to use Pack = 1):

[StructLayout(LayoutKind.Sequential, Pack = 1)]
class Data
{
    public int _int1;
    public int _int2;
    public short _short1;
    public long _long1;
}

Marshal the bytes into a new instance of the Data class:

var bytes = new byte[] { 1, 0, 0, 0, 2, 0, 0, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0 };
GCHandle gcHandle = GCHandle.Alloc(bytes, GCHandleType.Pinned);
var data = (Data)Marshal.PtrToStructure(gcHandle.AddrOfPinnedObject(), typeof(Data));
gcHandle.Free();

// Now data should contain the correct values.

Console.WriteLine(data._int1);    // Prints 1
Console.WriteLine(data._int2);    // Prints 2
Console.WriteLine(data._short1);  // Prints 3
Console.WriteLine(data._long1);   // Prints 4

For convenience you could write a static method on Data to do the conversion:

[StructLayout(LayoutKind.Sequential, Pack = 1)]
class Data
{
    public int _int1;
    public int _int2;
    public short _short1;
    public long _long1;

    public static Data FromBytes(byte[] bytes)
    {
        GCHandle gcHandle = GCHandle.Alloc(bytes, GCHandleType.Pinned);
        var data = (Data)Marshal.PtrToStructure(gcHandle.AddrOfPinnedObject(), typeof(Data));
        gcHandle.Free();
        return data;
    }
}

...

var data = Data.FromBytes(new byte[] {1, 0, 0, 0, 2, 0, 0, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0});

If you really wanted to you could write an explicit operator to convert from an array of bytes, to get the syntax in your OP. I would suggest just using Data.FromBytes() which is going to be a lot clearer IMO.

Still, just for completeness:

[StructLayout(LayoutKind.Sequential, Pack = 1)]
class Data
{
    public int _int1;
    public int _int2;
    public short _short1;
    public long _long1;

    public static explicit operator Data(byte[] bytes)
    { 
        GCHandle gcHandle = GCHandle.Alloc(bytes, GCHandleType.Pinned);
        var data = (Data)Marshal.PtrToStructure(gcHandle.AddrOfPinnedObject(), typeof(Data));
        gcHandle.Free();
        return data;
    }
}

...

var data = (Data)new byte[] {1, 0, 0, 0, 2, 0, 0, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0};
like image 162
Matthew Watson Avatar answered Dec 01 '25 18:12

Matthew Watson



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!