nixp.ru v3.0

18 января 2017,
среда,
00:22:18 MSK

DevOps с компанией «Флант»
DanilSoldatov написал 30 апреля 2008 года в 10:21 (532 просмотра) Ведет себя неопределенно; открыл 3 темы в форуме, оставил 4 комментария на сайте.

Привет программистам!

Не мог бы мне кто-нить пояснить такую ситуацию (пишу на Си).

Мне нужно получить последовательность байтов из 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 байтов

Как же все таки получить нужную последовательность, объясните мне дураку?

rgo
DanilSoldatov
Но реально там: TLV100000022. — вообщем всего 14 байтов

Почему же четырнадцать? Написано в объявлении 50, значит там не меньше. Другой вопрос, что же там лежит. Объясню:

TLV и 100000022 вопросов, думаю не возникает. Потом стоит '.' и непонятный символ, это два байта числа 302: 302%256 == 46, то есть '.' и 302/256 == 1, это непечатаемый символ SOH.

А после всего этого лежит байт со значением 13, то есть CR, и после этого три нулевых байта, которые беруться от значения 13 положенного в Len размер которого четыре байта.

Дальше продолжать?

DanilSoldatov

Да это все правильно, но где же вот эти байты? Их явно нет

vTLV302.var.Tag = 1;

vTLV302.var.Len = 23;

memcpy( vTLV302.var.DATE, «444444444447», 12 );

DanilSoldatov

ДА, все оказывается правильно было

просто я в отладчике смотрел,

а тот показывал page как строку а не как последовательность байтов

и обрывал ее на нулевом байте

Поэтому я посмотрел

page[0], page[1] и т.д. и все ок.

rgo
DanilSoldatov
Поэтому я посмотрел

page[0], page[1] и т.д. и все ок.

В gdb, чтобы он вывел массив размером 50 байт целиком, можно написать:

p (*page)@50

Это из предположения, что page — это указатель на массив, то есть, в данной ситуации, char*.

DanilSoldatov

А про выравнивание кто-нить что-нить слышал? Что-то все предложенные способы вроде испробовал — все равно лишние два байта появляются.

Вот такая последовательность получается из вішеуказанного 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)

};

rgo

Ты каким компилятором пользуешься? В gcc пишем так:

struct ... {
} __attribute__((packed));
ecobeingecobeing.ru
Экология и вегетарианство на благо всем живым существам Планеты.