выравнивание структуры по коду порта до 64-битной версии
-
22-08-2019 - |
Вопрос
У меня есть 32-битная сборка .NET, которая PInvokes на уровне C.Хочу портировать эту сборку на 64-битную.Я прочитал много документов, связанных с портированием на 64-битную версию, и все они, кажется, предполагают, что нам нужно позаботиться о выравнивании, если мы собираемся использовать структуры.
У меня возник общий вопрос, связанный с выравниванием структуры, и я хотел сначала его прояснить, чтобы ничего не пропустить.
Предположим, у меня есть точка входа C, которая принимает указатель структуры и в основном заполняет значения внутри.В этом коде C нет никаких директив упаковки, и все структуры .NET приведены в соответствие с параметром package=8.Поэтому, если я передам структуру со смежными целыми числами, я подумал, что может возникнуть проблема с интерпретацией данных, заполненных на уровне .NET, поскольку C по умолчанию будет использовать пакет = 4, а мы интерпретируем структуру как пакет = 8 в .NET. слой, поэтому подумал, что это может вызвать проблемы.Но, похоже, это не так.Данные, кажется, интерпретируются нормально.
Может ли кто-нибудь объяснить такое поведение?
Спасибо, Ниранджан
Решение
Я наткнулся на эту статью MSDNhttp://msdn.microsoft.com/en-us/library/aa366769(VS.85).aspx
Это предполагает, что указание уровня упаковки, превышающего естественное выравнивание типа, не меняет выравнивание типа.Таким образом, поскольку естественное выравнивание в упомянутом выше случае равно 4, установка упаковки на 8 на самом деле не меняет выравнивание структуры.Это объясняет поведение.
Другие советы
По умолчанию члены структуры или союза выравниваются по своим естественным границам;один байт для символа, два байта для короткого, четыре байта для целого числа и т. д.Если n присутствует, оно должно быть степенью 2, определяющей самое строгое естественное выравнивание для любой структуры или члена объединения.
Например, #pragma package(2) выравнивает int, long, long long, float, double, long double и указатели по границам двух байтов вместо их естественных границ выравнивания.Если n то же самое или больше, чем самое строгое выравнивание на вашей платформе (четыре на x86, восемь на SPARC V8 и 16 на SPARC V9), директива имеет влияние естественного выравнивания.
Я не уверен, поддерживает ли архитектура x86 8-байтовое выравнивание, хотя они поддерживают 64-битную среду.В конце концов, выравнивание по 4 байта на 64-битной платформе ничему не повредит.
Вы также можете использовать:#pragma align 8 (variable), чтобы сообщить компилятору, как вы хотите выровнять глобальную или статическую переменную.