Sign in to follow this  

C# binary reading and writing memory chunks?

This topic is 4199 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

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

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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

Share this post


Link to post
Share on other sites
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().

Share this post


Link to post
Share on other sites
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[i] + " ");
}
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[i] + " ");
}
}
}


Share this post


Link to post
Share on other sites

This topic is 4199 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this