Sign in to follow this  
B_old

[.net] Porting custom binary file loader from c++ to c#

Recommended Posts

B_old    689
Hi,

I want to port a loader for a custom binary file format from c++ to c# and have run into some questions I didn't think about before, because my experience with c# in that area is lacking.
In the cpp code I often use things like this

stream.read((char*)&struct, sizeof(Struct));
stream.read((char*)structs, numStructs * sizeof(Struct));

This seems to be problematic in c#, at least I haven't found a solution yet that works similar.
Looking around I found some potential variants.

  1. Use the BinaryReader to read one built-in type at a time, loop for arrays.

  2. Use the StructLayout attribute and write your own method to read a struct from a stream, loop for arrays.

  3. Use the MemoryMappedViewAccessor, which apparently can read structs and arrays thereof. Do I need to annotate the structs with StructLayout anyway?

I understand that the layout of .net structs can be changed by the compiler, which is why the cpp way is not working. Is this correct?
How would you go about this?

Share this post


Link to post
Share on other sites
turnpast    1011
The BinaryReader method is good when your format is complicated, variably sized, or not totally compatible with native .NET data types (RIFF headers for example). You can intersperse logic and loops, convert unusual data types and read the bytes directly if you need to. In my experience it is also a whole lot of work.

Marshaling structures directly from binary is fast, simple and (mostly) easy. It is also much harder to deal with oddities and may require you to use unsafe code.

I tend to lean toward the second if I can (because I am lazy). If you correctly set up the StructLayout attribute you can query its size, do pointer operations directly on it (for example cast an array of bytes to it) and use it in a number of Marshal operations. (see: Marshal.PtrToStructure, Marshal.SizeOf, Marshal.Copy etc.)

In general: If I am reading a single struct or an array of structs that are made up of compatible (fixed size) primitives than I use marshaling otherwise I use binary readers.

The memory mapped file stuff is new (for me and for .NET) and not something I have had time to play with yet, but I suspect it uses the marshaling calls internally when dealing with structs.

Hope this helps.

Share this post


Link to post
Share on other sites
B_old    689
Thanks for the answer. For now I went ahead and used the BinaryReader, but I'll consider the marshall method for later comparison!

Share this post


Link to post
Share on other sites

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