Привет программистам!
Не мог бы мне кто-нить пояснить такую ситуацию (пишу на Си).
Мне нужно получить последовательность байтов из 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 байтов
Как же все таки получить нужную последовательность, объясните мне дураку?
Последние комментарии
- OlegL, 17 декабря в 15:00 → Перекличка 21
- REDkiy, 8 июня 2023 года в 9:09 → Как «замокать» файл для юниттеста в Python? 2
- fhunter, 29 ноября 2022 года в 2:09 → Проблема с NO_PUBKEY: как получить GPG-ключ и добавить его в базу apt? 6
- Иванн, 9 апреля 2022 года в 8:31 → Ассоциация РАСПО провела первое учредительное собрание 1
- Kiri11.ADV1, 7 марта 2021 года в 12:01 → Логи catalina.out в TomCat 9 в формате JSON 1
Почему же четырнадцать? Написано в объявлении 50, значит там не меньше. Другой вопрос, что же там лежит. Объясню:
TLV и 100000022 вопросов, думаю не возникает. Потом стоит '.' и непонятный символ, это два байта числа 302: 302%256 == 46, то есть '.' и 302/256 == 1, это непечатаемый символ SOH.
А после всего этого лежит байт со значением 13, то есть CR, и после этого три нулевых байта, которые беруться от значения 13 положенного в Len размер которого четыре байта.
Дальше продолжать?
Да это все правильно, но где же вот эти байты? Их явно нет
vTLV302.var.Tag = 1;
vTLV302.var.Len = 23;
memcpy( vTLV302.var.DATE, «444444444447», 12 );
ДА, все оказывается правильно было
просто я в отладчике смотрел,
а тот показывал page как строку а не как последовательность байтов
и обрывал ее на нулевом байте
Поэтому я посмотрел
page[0], page[1] и т.д. и все ок.
В gdb, чтобы он вывел массив размером 50 байт целиком, можно написать:
Это из предположения, что page — это указатель на массив, то есть, в данной ситуации, char*.
А про выравнивание кто-нить что-нить слышал? Что-то все предложенные способы вроде испробовал — все равно лишние два байта появляются.
Вот такая последовательность получается из вішеуказанного 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)
};
Ты каким компилятором пользуешься? В gcc пишем так: