![]() |
|
Модераторы: Daevaorn |
![]()
|
|
| Курсант |
|
||||||||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 338 Регистрация: 21.2.2009 Где: Балашиха или Воро неж Репутация: нет Всего: 4 |
Всем доброго времени суток! У меня есть указатель void*, когда я пытаюсь читать из памяти структуру, расположенную по этому адресу, то первое поле читается нормально, второе - сдвинуто на 2 байта, третье - на 4 байта, то есть структура из памяти читается в искажённом виде.
Конкретно: занимаюсь разбором Ethernet-пакета, пакет считан из буфера приёмника в область памяти, есть указатель на область памяти void* Pointer. Сам пакет содержит в себе запрос от протокола ARP при подключении моего устройства в локальную сеть, хотя это не принципиально.
Для удобства работы у меня есть структуры Ethernet_Header, MAC_Address, Protocol_ID_in_Ethernet
Работая с указателем на пакет как с указателем на структуру Ethernet_Header, я пытаюсь выяснить, пакет какого протокола содержится в данных пакета Ethernet. Для этого я считываю из области памяти, на которую указывает Pointer, структуры типа MAC_Address и Protocol_ID_in_Ethernet:
После этого в переменных я получаю следующие значения
Я исходил из того, что в структуре не предусмотрены пропуски в два байта между полями. Компилятор почему-то посчитал по другому. Я наверное попробую объявить переменную типа Ethernet_Header и считать туда весь заголовок, но вообще изначально я не хотел ничего считывать ни в какие переменные, а использовать в качестве переменной саму область памяти, используя Pointer в качестве указателя. Т.е. мне не хотелось бы заниматься копированием области памяти, скопированной из буфера приёмника - это уже явно избыточные операции. Собственно вопрос: кто виноват и что делать? З.Ы. Компилятор CMC-ARM (для контроллеров с ARM-архитектурой). Это сообщение отредактировал(а) Курсант - 24.10.2014, 08:52 |
||||||||
|
|||||||||
| xvr |
|
||||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 7046 Регистрация: 28.8.2007 Где: Дублин, Ирландия Репутация: 60 Всего: 223 |
Стандарт С99, параграф 6.7.2.1 (Structure and union specifiers)
так что имеет право В С++ есть аналогичное замечание в п 9.2 абзац 21 -
Попробуйте аттрибут (или прагму) packed (не знаю, как она называется у CMC-ARM) |
||||
|
|||||
| Dem_max |
|
|||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1780 Регистрация: 12.4.2007 Репутация: 4 Всего: 39 |
используй
-------------------- Американские программисты долго не могли понять, почему русские при зависании Windоws всё время повторяют "Твой зайка написал" ("Yоur bunnу wrоte") |
|||
|
||||
| tzirechnoy |
|
|||
|
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1173 Регистрация: 30.1.2009 Репутация: 2 Всего: 16 |
Я посоветую не использовать прагмапаков, а работать с char *. Поначалу -- избавит от кучи проблем с пакингом, размером полей, byte order и прочей гадостью. При этом выигрыш от описания структур как структур -- в общем невелик, намакросах можно написать почти такжэ понятно, при этом скорость редко где уменьшытся, поскольку компиляторы обычно могут сокращать константные вычисления.
|
|||
|
||||
| Курсант |
|
||||||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 338 Регистрация: 21.2.2009 Где: Балашиха или Воро неж Репутация: нет Всего: 4 |
Спасибо всем за ответы! Прагма пак на CMC, похоже, не работает, а для отключения выравнивания полей структур есть директива __packed. У меня всё заработало, точнее, заголовок Ethernet-пакета удалось разобрать именно на те составляющие, из которых он состоит. Но дальше возникли трудности с разбором заголовка ARP-пакета, вложенного в Ethernet-пакет. А именно, структура заголовка Ethernet-пакета описывается так:
EthernetProtocol.h
До этого места всё работает нормально. Но как только я поправляю аналогичным образом описание заголовков ARP-пакетов: ARPProtocol.h
Начинаются проблемы. При компиляции появляется ругань на вот этот участок кода: EthernetProtocol.h
при этом даже если из EthernetProtocol.h убрать директивы packed, сообщения об ошибках всё равно остаются. То есть возникают проблемы, если в packed-структуре есть другие вложенные структуры. И я опять завис. Это сообщение отредактировал(а) Курсант - 24.10.2014, 21:03 |
||||||
|
|||||||
| tzirechnoy |
|
|||
|
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1173 Регистрация: 30.1.2009 Репутация: 2 Всего: 16 |
Это у Вас не вложэнные структуры, а дважды включённые файлы заголовков.
|
|||
|
||||
| Курсант |
|
||||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 338 Регистрация: 21.2.2009 Где: Балашиха или Воро неж Репутация: нет Всего: 4 |
Ну, в файлах заголовков у меня стоит
Поэтому дважды включение вроде бы исключено. А во-вторых как-то странно получается - добавляю __packed в описание структур ARP-заголовка, и сразу появляется два включения файла заголовка. Убираю __packed из описания структур ARP-заголовка - и всё компилируется (но на уровне ARP, судя по всему, работает неправильно). |
||||
|
|||||
| tzirechnoy |
|
|||
|
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1173 Регистрация: 30.1.2009 Репутация: 2 Всего: 16 |
То есть то, что у вас написано там вверху после слова "код" -- это фигня и не соответствует действительности. В общем, я мог бы догадаться и сам, да. Печально, но вряд ли здесь найдётся много жэлающих пытаться разбираться в секретном коде. |
|||
|
||||
| Курсант |
|
||||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 338 Регистрация: 21.2.2009 Где: Балашиха или Воро неж Репутация: нет Всего: 4 |
Мда, Вы правы, извините, но дело в том, что заголовочные файлы и си-файлы у меня достаточно объёмные, и приводить их полностью я посчитал излишним... Думаю, копаться в них нашлось бы ещё меньше желающих. Как ни странно, с ARP-заголовками работа идёт нормально даже без директив __packed. То ли компилятору одной директивы оказалось достаточно. Ну, я достаточно начинающий программист, поэтому пока займусь протоколами, а с директивами компилятора разберусь как-нибудь потом. Это работает, значит не будем ничего трогать. Спасибо большое за ответы. |
||||
|
|||||
![]()
|
| Правила форума "С++:Общие вопросы" | |
|
|
Добро пожаловать!
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn |
| 0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
| 0 Пользователей: | |
| « Предыдущая тема | C/C++: Общие вопросы | Следующая тема » |
|
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |