How to avoid object marshalling in IPC communication


#1

Hi,

my current project requires me to communicate between 32 bit and 64 bit builds of Juce via IPC (InterProcessConnection). The protocol I’ve implemented involves the exchange of simple, flat structs that consist of 32/64 bit agnostic primitive types (uint32, char[], bool, etc). Currently I simply push these as MemoryBlocks over the wire. I am not doing any endianess conversion, because I will not support PPC anyway.

The compiler however uses a different structure padding on 32 bit and 64 bit builds, so the structs do not align at both ends.

I really want to avoid any form of complex object marshalling (XML or similar), because that would be too much overhead in a real-time context.

Is there a way to force the same padding for both architectures? I know I can pack the structs to 1 byte alignment on Windows and OSX, but would much prefer to pack them to the 32 bit default padding in the 64 bit build instead. My client application needs the 32 bit default padding internally, so that’s an important point.

Any idea how to do that? How are you dealing this?

TIA


#2

#pragma pack(push, 1)
or attribute(packed)


#3

Yes, I used that already with these macros around a struct declaration:

#if JUCE_MAC #define PACKED_STRUCT(__Declaration__) __Declaration__ __attribute__((packed)) #else #define PACKED_STRUCT(__Declaration__) __pragma( pack(push, 1) ) __Declaration__ __pragma( pack(pop) ) #endif

However, this results in 1 byte alignment that can no longer be interpreted by my client application (not C++) which requires the default alignment on 32 bit builds.

Is there any way to force the 32 bit default alignment also in a 64 bit build?


#4

#pragma pack(4) ?


#5

I thought this was Microsoft specific, but, as I just discovered, for compatibility reasons it was also added to gcc, which is fine. After moving the largest members to the top of the struct, forcing a 4 byte boundary on both 32/64 bit builds did the trick. Thanks!

It is still beyond me though, how I am supposed to verify the alignment with appropriate assertions. A simple sizeof() is better than nothing, but the members may still be out of synch. I checked this one:

but interestingly enough, this method of testing returns the odd unaligned offsets! The physical layout is entirely hidden :?


#6

// Check alignment on 64 bits
jassert((reinterpret_cast(ptr) & 7) == 0)

// Check alignment on 32 bits
jassert((reinterpret_cast(ptr) & 3) == 0)

…etc…


#7

Thanks for your tips!

To close this thread, I want to report that only 1 byte alignment and packing worked for me. I was unable to reconstruct the default 32 bit alignment and padding on a 64 bit build.

To ensure better performance, I avoided using unevenly sized struct members, that is, I use uint16 for bool, sized all char* strings to multiples of 8, etc. This works fine now.