Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to convert a value type to byte[] in C#?

Tags:

arrays

c#

I want to do the equivalent of this:

byte[] byteArray;
enum commands : byte {one, two};
commands content = one;
byteArray = (byte*)&content;

yes, it's a byte now, but consider I want to change it in the future? how do I make byteArray contain content? (I don't care to copy it).

like image 551
Nefzen Avatar asked Jul 01 '09 11:07

Nefzen


People also ask

Can you print [] byte?

You can simply iterate the byte array and print the byte using System. out. println() method.

How do you convert int to byte value?

Solution 1int intValue = 2; byte byteValue = Convert. ToByte(intValue);

What is System byte [] in C#?

In C#, Byte Struct is used to represent 8-bit unsigned integers. The Byte is an immutable value type and the range of Byte is from 0 to 255.

How do you convert objects to bytes?

Write the contents of the object to the output stream using the writeObject() method of the ObjectOutputStream class. Flush the contents to the stream using the flush() method. Finally, convert the contents of the ByteArrayOutputStream to a byte array using the toByteArray() method.


2 Answers

To convert any value types (not just primitive types) to byte arrays and vice versa:

    public T FromByteArray<T>(byte[] rawValue)
    {
        GCHandle handle = GCHandle.Alloc(rawValue, GCHandleType.Pinned);
        T structure = (T)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(T));
        handle.Free();
        return structure;
    }

    public byte[] ToByteArray(object value, int maxLength)
    {
        int rawsize = Marshal.SizeOf(value);
        byte[] rawdata = new byte[rawsize];
        GCHandle handle =
            GCHandle.Alloc(rawdata,
            GCHandleType.Pinned);
        Marshal.StructureToPtr(value,
            handle.AddrOfPinnedObject(),
            false);
        handle.Free();
        if (maxLength < rawdata.Length) {
            byte[] temp = new byte[maxLength];
            Array.Copy(rawdata, temp, maxLength);
            return temp;
        } else {
            return rawdata;
        }
    }
like image 173
OregonGhost Avatar answered Nov 03 '22 23:11

OregonGhost


For anyone who's interested in how it works without using BitConverter you can do it like this:

// Convert double to byte[]
public unsafe byte[] pack(double d) {
    byte[] packed = new byte[8]; // There are 8 bytes in a double
    void* ptr = &d; // Get a reference to the memory containing the double
    for (int i = 0; i < 8; i++) { // Each one of the 8 bytes needs to be added to the byte array
        packed[i] = (byte)(*(UInt64 *)ptr >> (8 * i)); // Bit shift so that each chunk of 8 bits (1 byte) is cast as a byte and added to array 
    }
    return packed;
}

// Convert byte[] to double
public unsafe double unpackDouble(byte[] data) {
    double unpacked = 0.0; // Prepare a chunk of memory ready for the double
    void* ptr = &unpacked; // Reference the double memory
    for (int i = 0; i < data.Length; i++) {
        *(UInt64 *)ptr |= ((UInt64)data[i] << (8 * i)); // Get the bits into the right place and OR into the double
    }
    return unpacked;
}

In reality it's much easier and safer to use BitConverter but it's fun to know!

like image 25
Rob Sanders Avatar answered Nov 03 '22 22:11

Rob Sanders