| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > C/C++: Общие вопросы > Получить последовательность байтов из структуры |
| Автор: DanilSoldatov 30.4.2008, 09:14 |
| Привет программистам! Не мог бы мне кто-нить пояснить такую ситуацию (пишу на Си). Мне нужно получить последовательность байтов из 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 30.4.2008, 09:44 |
| Вообще-то то, как располагать структуру в памяти, определяет компилятор, в зависимости от настроек оптимизации (и просто под настроение) он может запросто вставлять пустые места между членами структуры и т.д. Далее, вот этим "char DATE[12];" ты объявляешь указатель на строку, который входит в структуру. Никто не обещал, что сама строка будет располагаться в этой же, либо соседней области памяти. Добавлено через 7 минут и 16 секунд Судя по названиям, ты все это будешь передавать по сети, могу предложить такой вариант, я так и делал. Сделай все типы пакетов - классами, и научи их упаковывать все нужные им данные самостоятельно (им то известны все размеры), последовательно их копируя в один буфер. Первые 3 символа - сигнатура пакета. Получатель создает класс такого же типа и уже он распаковывает их. |
| Автор: N0dwis 30.4.2008, 10:05 | ||
DATE - фактически и есть указатель на первый элемент, он не конвертируется. Но то, что 12 байт будут в структуре - ты прав, тут я поторопился... |
| Автор: DanilSoldatov 30.4.2008, 10:13 | ||||
как я понимаю они там должны быть, но ведь их нет (имею ввиду в байтовой последовательности)
Да, это пакеты для передачи по сети. В Дельфи у меня все работало(там я вместо структур использовал рекорды) Щас надо на чистый Си (в нем нет классов) все это перевести. Т.е. мне надо как угодно на выходе получить байты, расположенные в определенном порядке (согласно структуре пакета) Разве стркутуры это не лучший вариант? |
| Автор: N0dwis 30.4.2008, 10:56 |
| Только что проверил - у меня все в page как и должно быть... Похоже, это твой компилятор что-то мудрит... |
| Автор: DanilSoldatov 30.4.2008, 11:22 |
| ДА, все оказывается правильно было просто я в отладчике смотрел, а тот показывал page как строку а не как последовательность байтов и обрывал ее на нулевом байте Поэтому я посмотрел page[0], page[1] и т.д. и все ок. |
| Автор: N0dwis 30.4.2008, 11:32 |
| |
| Автор: bel_nikita 30.4.2008, 11:53 |
| Не забываем про http://forum.vingrad.ru/index.php?showtopic=24425&view=findpost&p=168844 |
| Автор: DanilSoldatov 30.4.2008, 14:41 | ||
Это как раз кстати. Что-то все предложенные способы вроде испробовал - все равно лишние два байта появляются. Вот такая последовательность получается из вішеуказанного 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 30.4.2008, 17:27 | ||
DanilSoldatov,
|