Модераторы: Daevaorn
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Получить последовательность байтов из структуры 
:(
    Опции темы
DanilSoldatov
Дата 30.4.2008, 09:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 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 байтов

Как же все таки получить нужную последовательность, объясните мне дуракуsmile?
PM MAIL   Вверх
N0dwis
Дата 30.4.2008, 09:44 (ссылка)    | (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 238
Регистрация: 18.9.2007
Где: Луганск

Репутация: нет
Всего: 4



Вообще-то то, как располагать структуру в памяти, определяет компилятор, в зависимости от настроек оптимизации (и просто под настроение) он может запросто вставлять пустые места между членами структуры и т.д.
Далее, вот этим "char  DATE[12];" ты объявляешь указатель на строку, который входит в структуру. Никто не обещал, что сама строка будет располагаться в этой же, либо соседней области памяти.

Добавлено через 7 минут и 16 секунд
Судя по названиям, ты все это будешь передавать по сети, могу предложить такой вариант, я так и делал.
Сделай все типы пакетов - классами, и научи их упаковывать все нужные им данные самостоятельно (им то известны все размеры), последовательно их копируя в один буфер. Первые 3 символа - сигнатура пакета. Получатель создает класс такого же типа и уже он распаковывает их.
PM MAIL   Вверх
maxim1000
Дата 30.4.2008, 09:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник
Сообщений: 3334
Регистрация: 11.1.2003
Где: Киев

Репутация: 17
Всего: 110



Цитата(N0dwis @  30.4.2008,  09:44 Найти цитируемый пост)
Далее, вот этим "char  DATE[12];" ты объявляешь указатель на строку, который входит в структуру. Никто не обещал, что сама строка будет располагаться в этой же, либо соседней области памяти.

нет, char DATE[12] - объявление массива
а уже в выражениях DATE чаще всего конвертироваться в указатель на первый элемент
но эти 12 байт будут точно в структуре и именно после len


--------------------
qqq
PM WWW   Вверх
N0dwis
Дата 30.4.2008, 10:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 238
Регистрация: 18.9.2007
Где: Луганск

Репутация: нет
Всего: 4



Цитата(maxim1000 @  30.4.2008,  09:57 Найти цитируемый пост)
нет, char DATE[12] - объявление массива
а уже в выражениях DATE чаще всего конвертироваться в указатель на первый элемент
но эти 12 байт будут точно в структуре и именно после len

DATE - фактически и есть указатель на первый элемент, он не конвертируется.
Но то, что 12 байт будут в структуре - ты прав, тут я поторопился... smile 
PM MAIL   Вверх
DanilSoldatov
Дата 30.4.2008, 10:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 9
Регистрация: 30.4.2008

Репутация: нет
Всего: нет



Цитата

но эти 12 байт будут точно в структуре и именно после len


как я понимаю они там должны быть, но ведь их нет (имею ввиду в байтовой последовательности)

Цитата

Судя по названиям, ты все это будешь передавать по сети, могу предложить такой вариант, я так и делал.
Сделай все типы пакетов - классами, и научи их упаковывать все нужные им данные самостоятельно (им то известны все размеры), последовательно их копируя в один буфер. Первые 3 символа - сигнатура пакета. Получатель создает класс такого же типа и уже он распаковывает их.


Да, это пакеты для передачи по сети. В Дельфи у меня все работало(там я вместо структур использовал рекорды)
Щас надо на чистый Си (в нем нет классов) все это перевести.
Т.е. мне надо как угодно на выходе получить байты, расположенные в определенном порядке (согласно структуре пакета)
Разве стркутуры это не лучший вариант?
PM MAIL   Вверх
N0dwis
Дата 30.4.2008, 10:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 238
Регистрация: 18.9.2007
Где: Луганск

Репутация: нет
Всего: 4



Только что проверил -  у меня все в page как и должно быть... 
Похоже, это твой компилятор что-то мудрит...
PM MAIL   Вверх
DanilSoldatov
Дата 30.4.2008, 11:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 9
Регистрация: 30.4.2008

Репутация: нет
Всего: нет



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

просто я в отладчике смотрел,
а тот показывал page как строку а не как последовательность байтов

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

Поэтому я посмотрел
page[0], page[1] и т.д. и все ок.
PM MAIL   Вверх
N0dwis
Дата 30.4.2008, 11:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 238
Регистрация: 18.9.2007
Где: Луганск

Репутация: нет
Всего: 4



 smile 
PM MAIL   Вверх
bel_nikita
Дата 30.4.2008, 11:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Эксперт
Сообщений: 2304
Регистрация: 12.10.2003
Где: Поезд №21/22 ( ст . Прага )

Репутация: 21
Всего: 47





--------------------
user posted image — регистрация доменов от 150 руб.
PM MAIL WWW ICQ   Вверх
DanilSoldatov
Дата 30.4.2008, 14:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 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)
};
PM MAIL   Вверх
MAKCim
Дата 30.4.2008, 17:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Воін дZэна
****


Профиль
Группа: Экс. модератор
Сообщений: 5644
Регистрация: 10.12.2005
Где: Менск, РБ

Репутация: 52
Всего: 207



DanilSoldatov, 

M
MAKCim
Модератор: Пользуйтесь тегом код!



--------------------
Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі ©

PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0526 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.