Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ x86/x64 structure alignment + .NET AnyCPU C++ library usage (calls/callbacks)

As my previous question had no success ("C# AnyCPU library using x86/x64 C API - packing structures, calls and callbacks"), I will write a more concise and abstract one.

THE PICTURE:

The company where I work has a software to be ported on 64 bit. The Software consists of a BASE library (C++ with C API) an two wrappers over the C API: a C++ wrapper and a .NET wrapper.

The C++ BASE library & C++ WRAPPER should have x86/x64 build configurations. The .NET WRAPPER should have only an AnyCPU build configuration.

Picking the right library from the .NET WRAPPER has been successfully completed (both C++ BASE libraries (x86/x64) are being loaded in two separate namespaces and depending on the size of IntPtr the right functions are called at runtime; this does not necessarily require for both libraries to be there, but only the one to be used).

THE PROBLEM:

All the structures in the BASE library are aligned on 4 bytes:

#pragma pack(push,4)

In order to have the code compile with NO warnings on 64-bit, I have added selective alignment (C++ BASE & C++ WRAPPER work like charms):

#ifdef WIN64
#pragma pack(push,8)
#else
#pragma pack(push,4)
#endif

The problem is related to the structures in .NET:

[StructLayout(LayoutKind.Sequential, Pack = 4, CharSet = CharSet.Unicode)]
    internal struct DBConnectionSettings{...}

This structure cannot have selective packing since AnyCPU is the only desired WRAPPER configuration.

It is very hard (LOTS AND LOTS OF PEFRORMANCE LOSS) to create separate structures aligned on 8 bytes in a different .NET namespace... Yet, this may be the only solution we may find fully working.

Falling back to 4-bytes alignment for both x86 and x64 issues LOTS of warnings as 100% of the structures are sensitive to packing, especially for the unary operators (problems only appear on x64 solution configuration with alignment on 4 bytes). Lots of crashes, the structures cannot be aligned unless we add dummy members. I should mention that the structure are grouped based on meaning or related to license / target OS (ifdefs). Adding padding (dummy) members to all the possibilities would demand months.

Aligning everything on 8 bytes is not a solution neither since we get crashes allover the place again - only for x86, x64 works nice - structure alignment requires again dummy (padding) members and grouping based on size.

THE CONCLUSION (QUESTIONS):

1) Is it possible for a C++ code to have alignment of 4 for both x86 and x64 solution configurations? How can this be accomplished?

2) What is the best alternative for x86 and x64 alignment? The pointer size definitely should rule the alignment (in my opinion). We are seeking to have FAST software, not necessarily memory-efficient (so far memory fingerprint is somewhere between 15mb and 2gb on x86 systems).

3) What special needs have the structures bearing function pointers have with respect to interop between .NET and C?

4) Any suggested alternative is highly appreciated.

We have been searching for more than one month on this internet (the one on our planet) but we have come nowhere. Some architects plead to use selective packing (4/8) while some argue that the software is not straight-forward and that it should be refactored. It s not my decision what to do, but I may bring ideas with good arguments. The software has been started in late 2000's, when the STL was buggy, so the BASE has its own containers optimized for God-knows-what. I should not express my opinion here since it's not Christian.

like image 761
ro0ter Avatar asked Apr 23 '13 07:04

ro0ter


1 Answers

Just fix the alignment problem on the C++ side. There should be no reason for x86 code to crash on 8 byte alignment, nor for x64 to crash on 4 byte alignment. #pragma pack(push,4) would be a suitable method. You may need another #pragma pack for internal SSE code, but that code shouldn't be exposed to .Net AnyCPU code.

If you get hundreds of warnings (ignoring perf. warnings of course), then the compiler agrees with my assessment that your code is suspect.

like image 181
MSalters Avatar answered Oct 06 '22 10:10

MSalters