Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ Specify Actual Size of Struct

I've come across a problem with interop between C# and C++ where I'm sharing memory between the two 'sides' of my application via a struct defined in both native and managed code. The struct on the native side is defined as such:

#pragma pack(push, 1)
        struct RayTestCollisionDesc {
                btVector3 hitPosition;
                btRigidBody* hitBody;

                RayTestCollisionDesc(btRigidBody* body, btVector3& position)
                        : hitBody(body), hitPosition(position) { }
        };
#pragma pack(pop)

And a similar struct is defined on the managed (C#) side. On C# the struct size is 20 bytes (as I would expect on a 32-bit system). However, despite the pragma pack directive, the struct size on the C++ size is still 32. For clarity here's the sizeof() from C++ of each of those types:

sizeof(btVector3) : 16 
sizeof(btRigidBody*) : 4
sizeof(RayTestCollisionDesc) : 32

Clearly pragma pack is only referring to packing between members of the struct, and not padding at the end of the struct (i.e. alignment). I also tried adding __declspec(align(1)) but that had no effect, and MSDN itself does say "__declspec(align(#)) can only increase alignment restrictions."

And FWIW I'm using the VS2013 compiler (Platform Toolset v120).

Is there a way to 'force' the struct size to 20 bytes?

like image 378
Xenoprimate Avatar asked Dec 07 '15 13:12

Xenoprimate


1 Answers

You are transferring data between two different compilers. In general, it is impossible to make this match. Especially if you transfer data from one computer to another.

First write a spec for the data that you are transferring. The spec CANNOT be a C++ or C# struct. The spec must be something like "four bytes this, four bytes that, two bytes a third thing..." and so on "with a total of 20 bytes", for example.

Then whether you use C++ or C#, or whether a totally different developer uses Objective-C code to read the data, you read an array of 20 bytes, take the 20 bytes, look at them, and fill whatever struct you want with these 20 bytes. And for writing, you do the opposite. Now it does not matter what C++ compiler you use, what weird pragmas you are using, it just works.

Or use something portable like JSON.

like image 51
gnasher729 Avatar answered Sep 30 '22 00:09

gnasher729