2016-10-15 5 views
2

Возможно ли для программы C напечатать определение структуры? Было бы здорово иметь имена пользователей, но достаточно упорядоченного списка типов данных (и длины массива в случае массивов).GCC - Распечатать определение структуры

Я искал инструкции препроцессора для достижения этого, но не смог найти. Существует ли препроцессорная директива, которая может захватить аннотированную часть кода и использовать ее как переменную #define. Если это так, я мог бы инициализировать некоторые переменные sting, чтобы удерживать значение переменных #define.

Например, структура, как это получить печатную как есть

struct foo{ 
int a; 
char b; 
short arr[6]; 
} 

или как этот

struct s{ 
int m1; 
char m2; 
short m3[6]; 
} 

Форматирование не важно, как долго, как структура может быть воссоздана из данных. Так что что-то вроде этого тоже хорошо:

s{int,char,short[10]} 

Just FYI это устройство с ограниченным доступом на основе ARM.

Я не хочу вручную копировать код структуры в инструкцию печати. Если код структуры изменяется, а оператор печати не изменяется, это приведет к неправильным результатам.

+0

Не в стандартном C, насколько я знаю. И определенно не через препроцессор C (под «переменной #define», вы имеете в виду макрос препроцессора C), поскольку он не имеет ни малейшего представления о том, как работает C. –

+2

@ Rhymoid не согласится на это; вы можете использовать препроцессор, чтобы сделать копию рассматриваемого кода для '#define structname_code ... ', а также создать его экземпляр. –

+0

«Я не хочу, чтобы вручную скопировать код структуры» - вы можете заставить программу читать собственный файл исходного кода. – usr2564301

ответ

1

Зачем вам это нужно, если у вас уже есть исходный код?

Но, в общем, компиляторы C не предлагают вариант, например. «список» всех структур, которые он видел во время компиляции. Компилятор сохранит таблицы внутренних символов, но никто не думал о необходимости их распечатки. Также могут быть сотни структур и типов во всех исходных и заголовочных файлах, прочитанных во время компиляции.

Обратите внимание, что имена типов, полей и переменных в основном присутствуют, чтобы дать смысл программисту. После компиляции многие имена исчезнут. Только глобальные переменные и отсутствующие внешние переменные сохраняют свое имя в объектном файле, чтобы иметь возможность разрешать их во время связывания, и после связывания эти имена больше не нужны. Компилятор, например, перевел a->b в смещение b, переведя туда место в память, где находится a.

+0

«Зачем вам это делать, если у вас уже есть исходный код?» У меня встроенное устройство IoT. На поле могло быть много таких устройств. Устройство отправит бинарные капли. Эти устройства могут работать с различными версиями прошивки, а структура blob может варьироваться в зависимости от версии прошивки. Обычный подход заключается в том, чтобы передать версию прошивки и сообщить группе о структурах blob для каждой версии. Чтобы усложнить ситуацию, память устройства может содержать данные, хранящиеся в предыдущих версиях прошивки. Я хотел бы сделать данные самоописательными. – Dojo

+0

Существуют обходные пути, которые не связаны с пониманием структуры. Но они беспорядочны и налагают ограничения. Мне нравится идея JSON/bJSON. Это единственный недостаток - это накладные расходы данных, как только вы заплатили эту цену, это создает очень гибкую информационную систему, где все узлы не должны быть в одной и той же версии для успешного обмена. – Dojo

+0

И причина, по которой я не буду вставлять структуру в sprintf, упоминается в самом вопросе. Может быть, в крайнем случае я бы это сделал, но я пытаюсь найти лучшие способы сделать это. Один пользователь фактически оставил довольно полезный взлом в комментарии. – Dojo

1

Существуют форматы объектных файлов, которые содержат необходимую информацию и позволяют осуществлять программный доступ. Один из них - Dwarf. Обычно отладчики используют эту информацию.

Я не думаю (но я не уверен), что можно получить доступ к отладочной информации для кода . Это отличие от программ на языках, которые работают в сложной системе времени выполнения, такой как Java или семейство .net. Они могут использовать размышления о себе.

В программах, написанных на традиционно скомпилированных языках, вы, вероятно, откроете объектный файл - возможно, сам исполняемый исполняемый файл! - и изучите его программно, как и отладчик. Учитывая это, можно предположить, что было бы легче проанализировать исходный код (который в C и C++ должен быть доступен для многих определений типов в виде файлов заголовков). Но для нетривиальных применений эта идея может обманывать, потому что компилятор использует лексику и анализирует источник для вас и помещает всю информацию в аккуратные структуры данных, где их можно легко получить. Эта часть процесса компиляции - т. Е.значительная часть передней части - должна была бы быть сделана вами, если вы работаете с источниками.

Смежные вопросы