0

I am trying to read data from a file which is being written by CArchive. I have the original source which is being used to read and write using CArchive. But, I am trying to read this through C# code. I am able to read much of the file, but I got stuck when I have to read array of struct written in the file.

I have seen other questions on stackoverflow but they didn't worked for me.

Read binary file into a struct

Reading a C/C++ data structure in C# from a byte array

What they have suggested is to use this function.

public static T ByteToType<T>(BinaryReader reader)
{
    byte[] bytes = reader.ReadBytes(Marshal.SizeOf(typeof(T)));

    GCHandle handle = GCHandle.Alloc(bytes, GCHandleType.Pinned);
    T theStructure = (T)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(T));
    handle.Free();

    return theStructure;
}

But this doesn't work fine for me.

So here is my C++ code:

Structure:

struct MyStruct
{
    WORD field1 : 1;
    WORD field2 : 1;
    WORD field3 : 1;
    WORD field4 : 1;
    WORD field5 : 1;
    WORD field6 : 1;
    WORD field7 : 1;
    WORD field8 : 1;
    WORD field9 : 1;
};

CArchive Read code:

m_data = new MyStruct[3600];
cArchiveReader.Read(m_data, 3600 * sizeof(MyStruct));

Now C# Code:

My struct

public struct MyStruct
{
    ushort field1;
    ushort field2;
    ushort field3;
    ushort field4;
    ushort field5;
    ushort field6;
    ushort field7;
    ushort field8;
    ushort field9;
}

**Reading Code:**

var stream = new MemoryStream(bytes);
var reader = new BinaryReader(stream);
for (int I=0; I<3600; I++)
{
    structureCollection.Add(ByteToType<NodeFlag>(reader));
}

Now after this call, when I check structureCollection, nodes data is not correct. For the sixth struct in the collection values for two fields are 256, and after 7th or 8th structure all fields are 256. Now this is wrong data. I have read this through C++ code and that worked fine. Fields value is either 1 or 0, but 256 data is totally invalid.

Community
  • 1
  • 1
fhnaseer
  • 7,159
  • 16
  • 60
  • 112
  • How does CArchive encode the file? Is it just a flat copy of the C++ struct? – Dirk May 31 '13 at 14:17
  • Your C++ fields are stored with the fields packed into 1 bit per field, but your C# fields are using 16 bits per field. I suspect the C++ data will be being padded out to 2 bytes per struct with the last 7 bits unused (set to 0). Does that tally with what you see in the binary file if you look at it in a hex editor? – Matthew Watson May 31 '13 at 14:23
  • @Dirk write code is something like this "cArchive.Write(m_data, length)" I don't have code right now, but it is similar to this. – fhnaseer May 31 '13 at 15:57
  • @MatthewWatson yup, I figured that out, for each one struct 2bytes are being written, but my C# struct is different. I need to rework on my C# struct code. – fhnaseer May 31 '13 at 15:58

1 Answers1

0

Your C++ structure is a bitfield. It will take up a single WORD/ushort in content.

Your C# version uses 9 ushorts you seem to read that length.

Balog Pal
  • 16,195
  • 2
  • 23
  • 37