views:

503

answers:

3

Okay, so i am continuing to work on my little game engine to teach me C#/C++ more. Now i am attempting to write a way of storing data in a binary format, that i created. (This is learning, i want to do this my self from scratch). What i am wondering what is the best way of dealing with variable length arrays inside a structure when reading it in C++?

E.g. Here is what i currently have for my structures:

 [StructLayout(LayoutKind.Sequential)]
    public struct FooBinaryHeader
    {
        public Int32 m_CheckSumLength;
        public byte[] m_Checksum;
        public Int32 m_NumberOfRecords;
        public FooBinaryRecordHeader[] m_BinaryRecordHeaders;
        public FooBinaryRecord[] m_BinaryRecords;
    }

    [StructLayout(LayoutKind.Sequential)]
    public struct FooBinaryRecordHeader
    {
        public Int32 m_FileNameLength;
        public char[] m_FileName;
        public Int64 m_Offset;
    }

    [StructLayout(LayoutKind.Sequential)]
    public struct FooBinaryRecord
    {
        public bool m_IsEncrypted;
        public Int64 m_DataSize;
        public byte[] m_Data;
    }

Now how would i go about in C++ to actually read this in as a structure in C++? I was kinda hoping to get around reading each of the elements one by one and copying them into a structure.

The only real tutorial i found on this is this: http://www.gamedev.net/community/forums/topic.asp?topic%5Fid=310409&whichpage=1&#1989200

I'll take a wild guess and say reading this into a C++ structure is not really possible correct?

A: 

Use Marshall.StructToPtr and copy length of structure.

csharptest.net
Can you explain more?
UberJumper
+2  A: 

There's no such thing as a variable length array in a structure.

Suppose I had a structure point such as

struct point
{
    int x;
    int y;
}

If I wanted an array of 5 of these, the compiler would essentially reserve space for 10 ints. What happens if I ask for an array of structures, of which each contains a variable length array? There's no way to align those in memory since we can't know how much space to reserve for each one.

What you can do is to declare a pointer to the type of which you want a variable length array, because a pointer is a constant size. Then, you allocate enough memory for however many instances of that type, and point to it that way. You'll probably need to also add a length field to the struct so you know exactly how far you can go past the pointer before you risk segfaulting.

It might get a little hairy going back and forth between managed and unmanaged code and allocating and freeing memory, but that's another good exercise for learning C++ and C# together, if anything.

Mark Rushakoff
A: 

You can read it from binary format mapping a copy of these structures. Each array should be treated as a pointer and you should have a integer with size of this array.

For example in

C#

    [StructLayout(LayoutKind.Sequential)]
    public struct A
    {
        public Int32 m_CheckSumLength;
        public byte[] m_Checksum;
    }

C++

    struct A {
        int length
        char* vector
    }

Notes: byte has the same size of char.

When you read from a binary you can read the first 4 byte (int is 32 aka 4 byte) and allocate 4 + (readed length) after that you can read directly to the allocated buffer and treat as a A structure.


Matteo Valdina