LINUX.ORG.RU

pack(8)->pack(1) and vise versa

 aligment, , , ,


0

5

(очень!)хочу найти тулзу которая может сгенерировать структуру и пребразование структур из packed(8) в упакованую по 1 и обратно..

в some_protocol.h есть структуры (форматы сетевых пакетов) в которых поля выровнены по 8 байт. То есть как в визальном-ц по умолчанию устроено так их в сеть и вываливают. И есть DSL который принимает (которому несложно объяснить и передать) только упакованные структуры :( Соответсвенно надо конвертить пакеты туда-сюда.

писать руками и сопровождать что-то типа

#pragma pack(8,push)
struct Foo {
  char uno;
};
#pragma pack(pop)

#pragma pack(1,push)
struct FooPacked {
  char uno;
};
#pragma pack(pop)
PackFoo(struct Foo *,struct FooPacked *);
UnpackFoo(struct FooPacked *,struct Foo *);
для 800 структур это застрелится :( Нужно что-то более автоматизированное

PS/ про endianes и кодировку строк лучше и не спрашивайте :)

★★★★★

Ответ на: комментарий от annulen

Макросом пробовал?

классический С-препроцессор на такое неспособен :-( взять описание структуры по имени, создать запись новой структуры и сгенерять конвертеры туда-сюда пройдясь по полям

возможно справится ++x17 шаблонная магия, но я так не колдунствую

MKuznetsov ★★★★★
() автор топика

Может, парсер написать? Взять что-нибудь типа libclang или обёртку над ним, да генерировать. Есть ещё pycparser, он весь на питоне.

i-rinat ★★★★★
()

хочу найти тулзу которая может сгенерировать структуру и пребразование структур из packed(8) в упакованую по 1 и обратно..

Зачем? На современных процессорах выравнивание не играет практически никакой роли. За подтверждением — в интеловские мануалы.

То, что ты хочешь, тривиально решается препроцессором, но твоей любимой IDE может снести крышу к чертям от такого. Сильно на любителя.

/* МАГИЯ */
#define DEFFIELD(TYPE, NAME) TYPE NAME;
#define CPYFIELD(TYPE, NAME) dst->NAME = src->NAME;
#define DEFSTRUCT(NAME) struct Name { NAME##_FIELDS(DEFFIELD) };
#define DEFPSTRUCT(NAME) struct Name##Packed { NAME##_FIELDS(DEFFIELD) };
#define DEFPACK(NAME) void Pack##NAME(const struct NAME *src, struct NAME##Packed *dst) { NAME##_FIELDS(CONV) }
#define DEFUNPACK(NAME) void Unpack##NAME(const struct NAME##Packed *src, struct NAME *dst) { NAME##_FIELDS(CONV) }

/* декларирование полей всех структур */
#define Foo_FIELDS(XX) XX(char, uno) XX(int, dos)
#define Bar_FIELDS(XX) XX(char, one) XX(float, two)
/* перечисление всех структур */
#define STRUCTS(XX) XX(Foo) XX(Bar)

/* генерируем обычные структуры*/
#pragma pack(8,push)
STRUCTS(DEFSTRUCT)
#pragma pack(pop)

/* генерируем запакованные структуры*/
#pragma pack(1,push)
STRUCTS(DEFPSTRUCT)
#pragma pack(pop)

/* Генерируем методы упаковки */
STRUCTS(DEFPACK)
/* методы распаковки */
STRUCTS(DEFUNPACK)

kawaii_neko ★★★★
()
Последнее исправление: kawaii_neko (всего исправлений: 1)
Ответ на: комментарий от kawaii_neko

Зачем? На современных процессорах выравнивание не играет практически никакой роли

затем что в данном случае по сети пакеты ходят с pack(8) а в DSL можно передать/принять pack(1). И процессоры тут вообще не при делах.

«/* генерируем обычные структуры*/

они УЖЕ до нас нагенерены (это спецификация протокола) и лежат в *.h. Повторять полные описания такими макросами - 100% допустить ошибку в форматах.

PS/ пока пошёл по пути „объяснить DSLю где в структурах находятся <<дырки>> от выравниваний“. То есть де-факто copy-paste с pack8 в pack1 и вставка uint8_t gap[N] где идёт выравнивание. Отладка предвидется весёлой-весёлой :) А сопровождение так вообще..

MKuznetsov ★★★★★
() автор топика

А потом все спрашивают, нафига нужны полноценные макросы. В компилтайме взять любую декларацию/реализацию и на компилтайм-сишке же императивно поправить или сгенерировать по ней другую — не, не нужно. Все молятся на шаблоны шаблонов.

В принципе написать на перле узкий парсер объявлений перлисту труда не составит, я так для фасма директиксные интерфейсы генерил давно-давно. Вся сложность была в адекватном [не]развертывании дефайнов, в общем-то, парсер почти тривиален, если хидеры отформатированы, либо можно прогнать через препроцессор, а затем через indent определенного формата.

arturpub ★★
()
Ответ на: комментарий от MKuznetsov

они УЖЕ до нас нагенерены (это спецификация протокола) и лежат в *.h.

В сторону gccxml, clang.cindex смотрел? Примеры использования есть в питоновской ctypeslib (gccxml в старых версиях, clang в новых).

amm
()

Привет, а не покажешь свой some_protocol.h или хотя бы его пухлую часть, я тут хотел бы попробовать распарсить это дело.

Oxdeadbeef ★★★
()
Ответ на: комментарий от MKuznetsov

классический С-препроцессор на такое неспособен :-(

А можно еще кастомный пре-препроцессор накостылить, на каком-нибудь перле. Ну, это если очень надо. Метапрограммирование, типа, и все такое.

anonymous
()
Ответ на: комментарий от amm

В сторону gccxml, clang.cindex смотрел? Примеры использования есть в питоновской ctypeslib (gccxml в старых версиях, clang в новых).

это в принципе хороший долгосрочный вариант. Получить xml и по нему сделать описания пакетов для DSL с указанием пробелов.

а пока типичный сценарий: «вам шашечки или ехать» :-) Да здравствует hindicode и sed средствами ide ! Криво, зато так можно ехать уже сейчас..

MKuznetsov ★★★★★
() автор топика

На c# через рефлекшен? Я вот только на прошлой неделе прирутил там смену BE->LE.

А на С, если ты можешь сгенерить для каждой структуры что-то вроде

#define STRUCT1_FIELDS \ STRUCT_FILED(int32_t, field1) \ STRUCT_FILED(int16_t, field2) \ STRUCT_FILED(int8_t, field3) \

То можно будет достаточно быстро сделать генерацию кода.

vromanov ★★
()
Ответ на: комментарий от MKuznetsov

это в принципе хороший долгосрочный вариант. Получить xml и по нему сделать описания пакетов для DSL с указанием пробелов.

https://github.com/DTC-protocol/DTC/blob/master/DTCProtocol.h

Там еще proto файл лежит. Можно рассмотреть вариант использования protobuf и генерации структур непосредственно для DSL.

amm
()
Ответ на: комментарий от amm

proto слишком свежая вещь - он нестабилен (спецификация протокола) и невсеми поддерживается, это раз. В proto невключены общие заголовки эт два (хоть и мелочь).

А потом это всё равно перекодирующая/альтернативно-транспортная прослойка (ога, есть ещё json и compact-json) и главные объявления это C struct, именно они используются в «паравозном» продукте (то есть точно корректны включая все фичи) и танцевать надо от них. Идея использовать gccxml и подобные скорее всего в дальнейшем сработает. Но к светлому будущему придётся копать через нынешнюю тьму :-)

MKuznetsov ★★★★★
() автор топика
Ответ на: комментарий от kawaii_neko

Зачем? На современных процессорах выравнивание не играет практически никакой роли. За подтверждением — в интеловские мануалы.

А что вы скажете о powerpc, arm, mips?

Dudraug ★★★★★
()
Ответ на: комментарий от MKuznetsov

они УЖЕ до нас нагенерены (это спецификация протокола) и лежат в *.h

В чем проблема изменить формат выдачи генератора?

Если же они наполняются вручную, нужно всего лишь провести единоразовое преобразование. Если исходный код адекватный (нет объявления полей через «,»), это решается тривиальными регэкспами.

А сопровождение так вообще...

Определись: ты хочешь напрячься один раз, а потом беззаботно жить (с макросами), или обречь на вечные муки себя и остальных? «Дырки для выравнивания» — полный провал, в нормальных конторах такой говнокод никогда не пройдет review.

kawaii_neko ★★★★
()
Ответ на: комментарий от Dudraug

А что вы скажете о powerpc, arm, mips?

Я скажу, что если архитектура специально не оговорена, речь идет о x86 или x86_64.

kawaii_neko ★★★★
()
Ответ на: комментарий от kawaii_neko

В чем проблема изменить формат выдачи генератора?

в том что генератор уже лет 10 как работает и выдаёт генерируемое в сеть :-)

полный провал, в нормальных конторах такой говнокод никогда не пройдет review.

/менеджерское примечание:/ спорный вопрос. В нормальных конторах платят за работу, которая заключается в выпуске конечного продукта, а не за красоты кода и тех.решений ;-) Потому-что деньги считают. Если говнокод позволяет проекту двигаться по срокам и этапам, то к нему конечно будет галочка TODO:переписать_нах , но она так и останется тудой до лучших времён:-)

к тому-ж более красивое и разумное решение уже подсказали.

MKuznetsov ★★★★★
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.