LINUX.ORG.RU

История изменений

Исправление vsrmis, (текущая версия) :

Эта библиотека умеет только TCP и RTU, а мне надо научиться разбирать пакет в независимости от того, от куда он пришел, но спасибо, я буду подсматривать в их код static_lab

Здесь a начинает указывать на буфер, который при этом является константным массивом. Далее Вы присваиваете полю данной структуры новые данные, что может повлечь ошибку защиты памяти. Недовольство компилятора пресекается приведением типа в си-стиле.

В целом здесь следует рассматривать буфер как поток данных, который следует последовательно читать и преобразовывать в структуру.

Я буду очень благодарен, если вы мне покажете как правильней архитектурно это сделать, и как создать указатель на сырые данные и с точностью до байта определить эти данные в нём, а потом это всё записать в структуру, где определить где начинаются и заканчиваются данные. trex6 http://images.gameru.net/image/34c11ae91c.png Вот, я нахожу это издевательством со стороны гугла

Sorcerer

Вы присвоили control значение только первого байта, когда разыменовывали указатель: *(char *). Сделайте так:

a->control = *(uint16_t *) (buf+2+a->size);

и получите то, что хотели.

А вообще мне непонятно: говорите «C», а программа на C++, - нехорошо обманывать людей.

Так не сработало( ошибка компиляции), но зато сработало так.

a->control = *(short *) (buf+3+a->size);
Но я не особо хочу использовать short, что знает, какой он будет размерности на другой платформе, да и не совсем правильно это. Я ведь не объявлял свою переменную control как short, я её объявил как unsigned:16, и хочу записать в неё 16 бит и не short.

Далее мой новый провальный эксперимент.

#include <iostream>
#pragma pack(push, 1)
struct P
{
  
  unsigned size:16;
  char* data;
  unsigned control:16;
};
#pragma pack(pop)

int main()
{
 
  char buf []= {0x05,0x00,'H','e','l','l','o',0x00,0x02,0x01};
  P* a = (P*)buf;
  
  a->control = *(short *) (buf+3+a->size);
  a->data = (char*)(buf+3);
  std::cout<<a->size<<std::endl;
  std::cout<<a->control<<std::endl;
  std::cout<<a->data[0]<<std::cout;
}
---------------------------
[alex@archalex MODBUS]$ g++ ./first.cpp
[alex@archalex MODBUS]$ ./a.out 
5
258
�0x6012c8[alex@archalex MODBUS]$ 
Я Создал массив char-ов, в котором в первых 2 байтах записал длинну строки - 5, после строки поставил 0 (меня учили на лабах по асму, что признак окончания строки - 0). Со скрипом в сердце присвоил control значение ( дурацкий short), и зпхотел это всё вывести на экран. Что я сделал не так?

Исходная версия vsrmis, :

Эта библиотека умеет только TCP и RTU, а мне надо научиться разбирать пакет в независимости от того, от куда он пришел, но спасибо, я буду подсматривать в их код static_lab

Здесь a начинает указывать на буфер, который при этом является константным массивом. Далее Вы присваиваете полю данной структуры новые данные, что может повлечь ошибку защиты памяти. Недовольство компилятора пресекается приведением типа в си-стиле.

В целом здесь следует рассматривать буфер как поток данных, который следует последовательно читать и преобразовывать в структуру.

Я буду очень благодарен, если вы мне покажете как правильней архитектурно это сделать, и как создать указатель на сырые данные и с точностью до байта определить эти данные в нём, а потом это всё записать в структуру, где определить где начинаются и заканчиваются данные. trex6 http://images.gameru.net/image/34c11ae91c.png Вот, я нахожу это издевательством со стороны гугла

Sorcerer

Вы присвоили control значение только первого байта, когда разыменовывали указатель: *(char *). Сделайте так:

a->control = *(uint16_t *) (buf+2+a->size);

и получите то, что хотели.

А вообще мне непонятно: говорите «C», а программа на C++, - нехорошо обманывать людей. [/qoute]

Так не сработало( ошибка компиляции), но зато сработало так.

a->control = *(short *) (buf+3+a->size);
Но я не особо хочу использовать short, что знает, какой он будет размерности на другой платформе, да и не совсем правильно это. Я ведь не объявлял свою переменную control как short, я её объявил как unsigned:16, и хочу записать в неё 16 бит и не short.

Далее мой новый провальный эксперимент.

#include <iostream>
#pragma pack(push, 1)
struct P
{
  
  unsigned size:16;
  char* data;
  unsigned control:16;
};
#pragma pack(pop)

int main()
{
 
  char buf []= {0x05,0x00,'H','e','l','l','o',0x00,0x02,0x01};
  P* a = (P*)buf;
  
  a->control = *(short *) (buf+3+a->size);
  a->data = (char*)(buf+3);
  std::cout<<a->size<<std::endl;
  std::cout<<a->control<<std::endl;
  std::cout<<a->data[0]<<std::cout;
}
---------------------------
[alex@archalex MODBUS]$ g++ ./first.cpp
[alex@archalex MODBUS]$ ./a.out 
5
258
�0x6012c8[alex@archalex MODBUS]$ 
Я Создал массив char-ов, в котором в первых 2 байтах записал длинну строки - 5, после строки поставил 0 (меня учили на лабах по асму, что признак окончания строки - 0). Со скрипом в сердце присвоил control значение ( дурацкий short), и зпхотел это всё вывести на экран. Что я сделал не так?