![]() |
|
Модераторы: Daevaorn |
![]()
|
|
| DanilSoldatov |
|
|||
|
Новичок Профиль Группа: Участник Сообщений: 9 Регистрация: 30.4.2008 Репутация: нет Всего: нет |
Привет программистам!
Не мог бы мне кто-нить пояснить такую ситуацию (пишу на Си). Мне нужно получить последовательность байтов из union SENDPRICE в массиве char page[50]. Объявление следующее: struct TLVHADPrefix { char Protocol[3]; char Version; }; struct TLVHAD { struct TLVHADPrefix Prefix; char WSCode[8]; WORD OperCode; DWORD Len; }; union SENDPRICE { char page[50]; struct { struct TLVHAD Header; WORD Tag; WORD Len; char DATE[12]; } var; }; Затем в теле функции я присваиваю значения членам структуры - члена union SENDPRICE: union SENDPRICE vTLV302; // Объявление memcpy( vTLV302.var.Header.Prefix.Protocol, "TLV", 3 ); vTLV302.var.Header.Prefix.Version = '1'; memcpy( vTLV302.var.Header.WSCode, "00000022", 8 ); vTLV302.var.Header.OperCode = 302; vTLV302.var.Header.Len = 13; vTLV302.var.Tag = 1; vTLV302.var.Len = 23; memcpy( vTLV302.var.DATE, "444444444447", 12 ); и смотрю, что появилось в page[50], ожидая там увидеть всю эту последовательность из 3 + 1 + 8 + 2 + 4 + 12 + 2 + 2 = 34 байтов (при чем в таком же порядке как в структуре ). Но реально там: TLV100000022. - вообщем всего 14 байтов Если же я ставлю в объявлении элемент DATE[12]; на первое место вот так (это я делал для эксперимента, хотя для моей задачи это не подходит): union SENDPRICE { char page[50]; struct { char DATE[12]; struct TLVHAD Header; WORD Tag; WORD Len; } var; }; то получаю 444444444447TLV100000022. - 26 байтов Как же все таки получить нужную последовательность, объясните мне дураку |
|||
|
||||
| N0dwis |
|
|||
|
Бывалый ![]() Профиль Группа: Участник Сообщений: 238 Регистрация: 18.9.2007 Где: Луганск Репутация: нет Всего: 4 |
Вообще-то то, как располагать структуру в памяти, определяет компилятор, в зависимости от настроек оптимизации (и просто под настроение) он может запросто вставлять пустые места между членами структуры и т.д.
Далее, вот этим "char DATE[12];" ты объявляешь указатель на строку, который входит в структуру. Никто не обещал, что сама строка будет располагаться в этой же, либо соседней области памяти. Добавлено через 7 минут и 16 секунд Судя по названиям, ты все это будешь передавать по сети, могу предложить такой вариант, я так и делал. Сделай все типы пакетов - классами, и научи их упаковывать все нужные им данные самостоятельно (им то известны все размеры), последовательно их копируя в один буфер. Первые 3 символа - сигнатура пакета. Получатель создает класс такого же типа и уже он распаковывает их. |
|||
|
||||
| maxim1000 |
|
|||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Участник Сообщений: 3334 Регистрация: 11.1.2003 Где: Киев Репутация: 17 Всего: 110 |
нет, char DATE[12] - объявление массива а уже в выражениях DATE чаще всего конвертироваться в указатель на первый элемент но эти 12 байт будут точно в структуре и именно после len -------------------- qqq |
|||
|
||||
| N0dwis |
|
|||
|
Бывалый ![]() Профиль Группа: Участник Сообщений: 238 Регистрация: 18.9.2007 Где: Луганск Репутация: нет Всего: 4 |
DATE - фактически и есть указатель на первый элемент, он не конвертируется. Но то, что 12 байт будут в структуре - ты прав, тут я поторопился... |
|||
|
||||
| DanilSoldatov |
|
||||
|
Новичок Профиль Группа: Участник Сообщений: 9 Регистрация: 30.4.2008 Репутация: нет Всего: нет |
как я понимаю они там должны быть, но ведь их нет (имею ввиду в байтовой последовательности)
Да, это пакеты для передачи по сети. В Дельфи у меня все работало(там я вместо структур использовал рекорды) Щас надо на чистый Си (в нем нет классов) все это перевести. Т.е. мне надо как угодно на выходе получить байты, расположенные в определенном порядке (согласно структуре пакета) Разве стркутуры это не лучший вариант? |
||||
|
|||||
| N0dwis |
|
|||
|
Бывалый ![]() Профиль Группа: Участник Сообщений: 238 Регистрация: 18.9.2007 Где: Луганск Репутация: нет Всего: 4 |
Только что проверил - у меня все в page как и должно быть...
Похоже, это твой компилятор что-то мудрит... |
|||
|
||||
| DanilSoldatov |
|
|||
|
Новичок Профиль Группа: Участник Сообщений: 9 Регистрация: 30.4.2008 Репутация: нет Всего: нет |
ДА, все оказывается правильно было
просто я в отладчике смотрел, а тот показывал page как строку а не как последовательность байтов и обрывал ее на нулевом байте Поэтому я посмотрел page[0], page[1] и т.д. и все ок. |
|||
|
||||
| N0dwis |
|
|||
|
Бывалый ![]() Профиль Группа: Участник Сообщений: 238 Регистрация: 18.9.2007 Где: Луганск Репутация: нет Всего: 4 |
|
|||
|
||||
| bel_nikita |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Эксперт Сообщений: 2304 Регистрация: 12.10.2003 Где: Поезд №21/22 ( ст . Прага ) Репутация: 21 Всего: 47 |
Не забываем про выравнивание в структурах
|
|||
|
||||
| DanilSoldatov |
|
|||
|
Новичок Профиль Группа: Участник Сообщений: 9 Регистрация: 30.4.2008 Репутация: нет Всего: нет |
Это как раз кстати. Что-то все предложенные способы вроде испробовал - все равно лишние два байта появляются. Вот такая последовательность получается из вішеуказанного union SENDPRICE: 84 76 86 17 -------------TLV17 28 0 0 0 --------------DWORD len =28 48 48 48 48 48 48 57 57 ----------------WSCode[8] = 00000099 46 1 ---------------WORD OperCode=302 0 0 -----------------лишние байты 1 0 -----------------WORD Tag = 1 14 0 ------------------WORD len = 14 48 53 49 48 48 55 48 48 48 48 48 48 -----------------DATE[12]= 051007000000 Делал так: #pragma pack(push, _Struct, 1) struct TLVHAD { TLVHADPrefix Prefix; DWORD Len; TermID WSCode; WORD OperCode; }; #pragma pack(pop, _Struct) union SENDPRICE { char page[35]; #pragma pack(push, _Struct, 1) struct { struct TLVHAD Header; WORD Tag; WORD Len; MaxDATE DATE; } var; // 34 #pragma pack(pop, _Struct) }; |
|||
|
||||
| MAKCim |
|
|||
![]() Воін дZэна ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 5644 Регистрация: 10.12.2005 Где: Менск, РБ Репутация: 52 Всего: 207 |
DanilSoldatov,
-------------------- Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі © |
|||
|
||||
![]()
|
| Правила форума "С++:Общие вопросы" | |
|
|
Добро пожаловать!
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn |
| 0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
| 0 Пользователей: | |
| « Предыдущая тема | C/C++: Общие вопросы | Следующая тема » |
|
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |