2013-04-23 2 views
6

Как мой предыдущий вопрос не имел успеха («C# AnyCPU-библиотека с использованием x86/x64 C API - структуры упаковки, обратные вызовы и обратные вызовы») , Я напишу более краткий и абстрактный.C++ x86/x64 выравнивание структуры + использование библиотеки AnyCPU C++ (вызовы/обратные вызовы)

КАРТИНА:

Компания, где я работаю есть программное обеспечение, чтобы быть портирована на 64 бит. Программное обеспечение состоит из BASE-библиотеки (C++ с C API) двумя оболочками над C API: оболочкой C++ и .NET-оболочкой.

Библиотека C++ BASE & C++ WRAPPER должен иметь конфигурацию сборки x86/x64. .NET WRAPPER должен иметь только конфигурацию сборки AnyCPU.

Сбор правильной библиотеки из .NET WRAPPER был успешно завершен (обе библиотеки C++ BASE (x86/x64) загружаются в два разных пространства имен и в зависимости от размера IntPtr вызываются во время выполнения; не обязательно требует, чтобы обе библиотеки были там, но только тот, который будет использоваться).

ПРОБЛЕМА:

Все структуры в базовой библиотеки выравниваются по 4 байта:

#pragma pack(push,4) 

Для того чтобы иметь код компилируется без предупреждений, на 64-битной, у меня есть добавлено селективное выравнивание (C++ БАЗ & C++ WRAPPER работать как прелести):

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

проблема заключается в том связанный со структурами в .NET:

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

Эта структура не может иметь селективную упаковку, поскольку AnyCPU является единственной требуемой конфигурацией обертки.

Очень сложно (МНОГО И МНОГИЕ ПОТЕРИ ПЕЧАТИ) создавать отдельные структуры, выровненные по 8 байтам в другом пространстве имен .NET ... Однако это может быть единственное решение, которое мы можем найти в полной мере.

Возврат к 4-байтовому выравниванию для проблем x86 и x64. МНОГО предупреждений, поскольку 100% структур чувствительны к упаковке, особенно для унарных операторов (проблемы появляются только в конфигурации решения x64 с выравниванием по 4 байтам). Много сбоев, структуры не могут быть выровнены, если мы не добавим фиктивных членов. Следует отметить, что структура сгруппирована по значению или связана с лицензией/целевой ОС (ifdefs). Добавление дополнений (фиктивных) участников ко всем возможностям потребует месяцев.

Выравнивание всего по 8 байт не является решением ни с тех пор, как мы снова получаем аварийные ситуации, только для x86, x64 работает хорошо - для выравнивания структуры требуются снова фиктивные (дополняющие) элементы и группировка по размеру.

вывода (вопросы):

1) Можно для кода C++, чтобы иметь выравнивание 4 для x86 и x64 решений конфигураций? Как это можно сделать?

2) Какая оптимальная альтернатива для выравнивания x86 и x64? Размер указателя определенно должен регулировать выравнивание (на мой взгляд). Мы стремимся иметь программное обеспечение FAST, не обязательно эффективное для памяти (до сих пор память отпечатков пальцев находится где-то между 15 МБ и 2 ГБ на системах x86).

3) Какие особые потребности имеют структуры, несущие указатели на функции в отношении взаимодействия между .NET и C?

4) Любая предлагаемая альтернатива высоко ценится.

Мы искали более одного месяца в этом интернете (тот, что на нашей планете), но мы никуда не пришли. Некоторые архитекторы умоляют использовать выборочную упаковку (4/8), в то время как некоторые утверждают, что программное обеспечение не прямолинейно и что оно должно быть реорганизовано. Это не мое решение, что делать, но я могу привести идеи с хорошими аргументами. Программное обеспечение было запущено в конце 2000-х, когда STL был глючит, поэтому у BASE есть свои контейнеры, оптимизированные для богопознания. Я не должен выражать свое мнение здесь, так как это не христианин.

ответ

1

Просто исправьте проблему выравнивания на стороне C++. Не должно быть причин для сбоя кода x86 при выравнивании по 8 байт, а также для сбоя x64 при выравнивании по 4 байт. #pragma pack(push,4) был бы подходящим методом. Вам может понадобиться еще один #pragma pack для внутреннего кода SSE, но этот код не должен быть открыт .Net AnyCPU.

Если вы получаете сотни предупреждений (игнорируя, конечно, предупреждения), то компилятор согласен с моей оценкой, что ваш код подозрительный.

+0

Hi MSalters, Без какого-либо ввода было решено, что будет выполнена перегруппировка, независимо от того, какие лицензии зависят от системных зависимых структур. Тем не менее, я оставлю эту тему открытой для любых других решений, которые могут быть опубликованы. Мне просто интересно, что можно сделать с таким кодом ..... PS: это не мой код;) – ro0ter

Смежные вопросы