![]() |
|
Модераторы: Daevaorn |
![]()
|
|
| bel_nikita |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Эксперт Сообщений: 2304 Регистрация: 12.10.2003 Где: Поезд №21/22 ( ст . Прага ) Репутация: 21 Всего: 47 |
Есть структуры:
struct DspErrorParametr{ unsigned short UniqueNumber; unsigned short Command; unsigned short ErrorNumber; unsigned short ParameterOrder; unsigned short ParameterError; }; размер этой структуры sizeof(DspErrorParametr)=10; struct DspErrorParametr{ unsigned short UniqueNumber; unsigned short Command; unsigned short ErrorNumber; unsigned short ParameterOrder; unsigned short ParameterError; union{ unsigned short wErrorValue; } ErrorValue; }; размер этой структуры sizeof(DspErrorParametr)=12; struct DspErrorParametr{ unsigned short UniqueNumber; unsigned short Command; unsigned short ErrorNumber; unsigned short ParameterOrder; unsigned short ParameterError; union{ unsigned short wErrorValue; unsigned long dwErrorValue; } ErrorValue; }; размер этой структуры sizeof(DspErrorParametr)=16 вместо 14 !!!!!!!!!!!!! sizeof(unsigned long)=4! Не могу понять откуда берутся еще 2 байта? Перестановка в union не помогает. |
|||
|
||||
| automax |
|
|||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 54 Регистрация: 30.9.2002 Репутация: нет Всего: нет |
Есть подозрение на выравнивание по 4-х байтной границе.
|
|||
|
||||
| RAN |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 709 Регистрация: 14.3.2003 Где: Щёлково Моск.обл. Репутация: 5 Всего: 6 |
Я тоже занимался этими вопросами. В компиляторах есть опции для изменения выравнивания в структурах.
Если хочешь разобраться, что куда поместилось, то сделай break в проге и вычисляй значения struct DspErrorParametr a; (unsigned)&a.Command - (unsigned)&a и т.д. Я такое с классами проделывал. Очень полезно. Лучше понимаешь как надо данные в классе размещать. Уже не будешь писать: class A { char ch1; int i1; char ch2; long l1; char ch3; }; |
|||
|
||||
| RAN |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 709 Регистрация: 14.3.2003 Где: Щёлково Моск.обл. Репутация: 5 Всего: 6 |
long выравнивается по 4 байтам от начала структуры, чтоб быстрее работало. А так как ты сделал union, то и short тоже. У тебя после ParameterError 2 байта не будут использоваться. |
|||
|
||||
| RAN |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 709 Регистрация: 14.3.2003 Где: Щёлково Моск.обл. Репутация: 5 Всего: 6 |
Кстати, попробуй использовать double. Получишь выравнивание по 8 байтам.
|
|||
|
||||
| bel_nikita |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Эксперт Сообщений: 2304 Регистрация: 12.10.2003 Где: Поезд №21/22 ( ст . Прага ) Репутация: 21 Всего: 47 |
Спасибо!
До меня дошло. |
|||
|
||||
| DENNN |
|
|||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 3878 Регистрация: 27.3.2002 Где: Москва Репутация: 1 Всего: 43 |
см в MSDN #pragma pack
|
|||
|
||||
| knave |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 320 Регистрация: 6.3.2003 Где: Санкт-Питербург ( Россия) Репутация: 1 Всего: 5 |
#pragma pack (1) // выравнивание по одному байту
#pragma pack (2) // выравнивание по 2-м байту #pragma pack (4) // выравнивание по 4-м байту -------------------- С наилучшими пожеланиями !!! |
|||
|
||||
| bel_nikita |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Эксперт Сообщений: 2304 Регистрация: 12.10.2003 Где: Поезд №21/22 ( ст . Прага ) Репутация: 21 Всего: 47 |
Не помогает
Или я не так делаю #pragma pack (push, 4) ..... .... #pragma pack (pop) |
|||
|
||||
| knave |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 320 Регистрация: 6.3.2003 Где: Санкт-Питербург ( Россия) Репутация: 1 Всего: 5 |
Конечно ты нетак делаеш, я же написал
#pragma pack (1) // выравнивание по одному байту Пропиши это вначале cpp например или в каком нить h -------------------- С наилучшими пожеланиями !!! |
|||
|
||||
| bel_nikita |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Эксперт Сообщений: 2304 Регистрация: 12.10.2003 Где: Поезд №21/22 ( ст . Прага ) Репутация: 21 Всего: 47 |
так много warning'ов
у меня структура в *.Н. Этот хидер много где включается. надо чтоб, только одну структуру выровнял. |
|||
|
||||
| bel_nikita |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Эксперт Сообщений: 2304 Регистрация: 12.10.2003 Где: Поезд №21/22 ( ст . Прага ) Репутация: 21 Всего: 47 |
после #pragma pack (1)
у меня прога вообще не работает |
|||
|
||||
| bel_nikita |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Эксперт Сообщений: 2304 Регистрация: 12.10.2003 Где: Поезд №21/22 ( ст . Прага ) Репутация: 21 Всего: 47 |
Спасибо всем за советы.
Вот дошли наконец руки, разобрался. А теперь кому интересно, или у кого возникают проблемы с выравниванием (а если не возникают, то с временами возникнут Типа дополню MSDN Вообще-то выравнивание, коварная штука. Вот пример: первая структура: typedef struct _Struct1{ unsigned long ulPar1; // DWORD unsigned short ushPar2; // WORD unsigned short ushPar3; // WORD } Struct1; sizeof(Struct1)=8. Все отлично! вторая структура: typedef struct _Struct2{ unsigned long ulPar1; // DWORD unsigned short ushPar2; // WORD } Struct2; sizeof(Struct2)=8, вместо 6! (Кто знает в чем фокус - может дальше не читать Где справедливость? А справедливость надо поискать в #pragma pack(n). #pragma pack(n) - задает границы упаковки элементов, где n - граница выравнивания. #pragma pack(n) - действует только на Declaration. Возможные границы выравнивания: 1, 2, 4, 8, 16. По дефолту выравнивание идет по 8-ми байтной границе(VC++). Но лучше применять следующую конструкцию: .... #pragma pack(push, _identifier, n)// Входим в блок выравнивания по n-байтной границе ... // То что требуется выровнять - равняем ... #pragma pack(pop, _identifier)// Выходим из блока .... Не-еее, закалебаюсь писать, лучше пример кода приведу, будет понятнее и нагляднее. typedef struct _Struct1 { /*000*/ unsigned short Par1; /*002*/ unsigned short Par2; /*004*/ union{ unsigned long Par3; unsigned short Par4; /*008*/ } Union; } Struct1; // sizeof(Struct1)=8; OK typedef struct _Struct2 { /*000*/ unsigned short Par1; /*002*/ unsigned short Par2; /*004*/ unsigned short Par3; // Выравнивание вставляет компилер!!! /*006*/ // А здесьсь прячутся 2 байта /*008*/ union{ unsigned long Par4; unsigned short Par5; /*012*/ } Union; } Struct2; // sizeof(Struct2)=12; ERROR! #pragma pack(push, _start, 2) // Начинаем выравнивание по двубайтной границе typedef struct _Struct { /*000*/ unsigned short Par1; /*002*/ unsigned short Par2; /*004*/ unsigned short Par3; // Нет проблем /*006*/ union{ unsigned long Par4; unsigned short Par5; /*010*/ } Union; } Struct; // sizeof(Struct2)=10; То что надо! #pragma pack(pop, _start) // Заканчиваем выравнивание и компилятор дальше выравнивает по Default'у Надеюсь моя писанина кому-нить будет полезна. Ведь я писал это не от того что я такой вумный, а для того, что это может пригодится, и не мучаться от того, что данные из буфера забираются/кладутся не так, как хотелость бы. Во, как получается, сам задал вопрос на форуме и сам дал на него ответ |
|||
|
||||
![]()
|
| Правила форума "С++:Общие вопросы" | |
|
|
Добро пожаловать!
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn |
| 0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
| 0 Пользователей: | |
| « Предыдущая тема | C/C++: Общие вопросы | Следующая тема » |
|
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |