Skip to main content
gamedev.net
🔒 Locked

C# binary reading and writing memory chunks?

Started by mits Jun 13, 2006 at 1:12 PM 4 replies 7.4k views
Original Post
mits
mits
Hi, I wonder how can I read a memory chunk and convert it in a byte array in c#. To be more specific, suppose I have a class like this: class Numbers { public int x, y, z; public float a, b, c; } How can I convert it in an array of bytes in which I'll know that the first 12 bytes will be the integers and the next 12 will be the floats? After that what must I do to reconvert it to the class object it was before? In c++ using pointers made it easy but here in c# seems a little more difficult. Any hint would be helpful. Thanks
Nightski
Nightski
If all you need is a pointer to the struct in memory, you can obtain one in C#. You just need to wrap your pointer code in an unsafe code block.

unsafe
{
byte* b = ...
}

Once you have an array of bytes you can convert it back to an int or whatever using the BitConverter class.

To really solve your problem though it would be necessary to see why you need to convert it to this format. Are you passing it to a function that requires a pointer? If so just use the unsafe code method and pass the pointer. That way you don't have to worry about converting the data back. You may have to pin the data however as the GC can move data around in memory making your pointers invalid. Searching C# unsafe on google would probably be a good start.
mits
mits
Thanks for the answers. I think serialization would be a good start. I am not interested in unmanaged code. For that purpose, C++ is the perfect solution.
Thanks again
abnormal
abnormal
another way (e.g. if you can't or don't want to modify the struct or class) is just to throw the data to a memory stream with help of the BinaryWriter class:

MemoryStream memStream = new MemoryStream();BinaryWriter writer = new BinaryWriter(memStream);writer.Write(x);writer.Write(y);writer.Write(z);writer.Write(a);writer.Write(b);writer.Write(c);writer.Close();


Now you have your byte array in memStream.ToArray().
Microsoft DirectX MVP. My Blog: abi.exdream.com
Nightski
Nightski
I don't think serialization will work because it doesn't serialize the data directly. It adds extra context information and headers to the data.

To test this you can use the following code -
You will see that the unsafe version outputs the correct bytes but the serialization data is a whopping 183 bytes of info for just 24 bytes of data.

The other option would be to use reflection and traverse the object heirarchy and build your byte[] one step at a time using BitConverter for each member.

   class Program    {        [Serializable]        class Numbers        {            public int x, y, z;            public float a, b, c;        }        static void Main(string[] args)        {            Numbers num = new Numbers();            num.x = 5;            num.y = 10;            num.z = 15;            num.a = 5.523f;            num.b = 2.356f;            num.c = 6.432f;            int size = sizeof(int) * 3 + sizeof(float) * 3;            unsafe            {                fixed (int* n = &num.x)                {                    byte* b = (byte*)n;                    for (int i = 0; i < size; i++)                        Console.Write(b + " ");                }                Console.WriteLine();            }            MemoryStream ms = new MemoryStream();            BinaryFormatter bf = new BinaryFormatter();            bf.Serialize(ms, num);            byte[] bytes = ms.ToArray();            for (int i = 0; i < bytes.Length; i++)            {                Console.Write(bytes + " ");            }        }    }

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.