Извлечь поля структуры C - PullRequest
14 голосов
/ 12 января 2010

Мне часто приходится писать код на других языках, которые взаимодействуют со структурами Си. Чаще всего это включает в себя написание кода Python с модулями struct или ctypes .

Итак, у меня будет файл .h, полный структурных определений, и я должен вручную прочитать их и продублировать эти определения в моем коде Python. Это отнимает много времени и подвержено ошибкам, и трудно поддерживать синхронизацию двух определений, когда они часто меняются.

Существует ли какой-либо инструмент или библиотека на каком-либо языке (необязательно C или Python), который может взять файл .h и создать структурированный список его структур и их полей? Я хотел бы иметь возможность написать скрипт для автоматической генерации моих структурных определений в Python, и я не хочу обрабатывать произвольный C-код для этого. Регулярные выражения будут отлично работать примерно в 90% случаев, а затем будут вызывать бесконечные головные боли в оставшиеся 10%.

Ответы [ 7 ]

10 голосов
/ 12 января 2010

Если вы компилируете свой C-код с помощью отладки (-g), pahole ( git ) может дать вам точные используемые структуры.

$ pahole /bin/dd
…
struct option {
        const char  *              name;                 /*     0     8 */
        int                        has_arg;              /*     8     4 */

        /* XXX 4 bytes hole, try to pack */

        int *                      flag;                 /*    16     8 */
        int                        val;                  /*    24     4 */

        /* size: 32, cachelines: 1, members: 4 */
        /* sum members: 24, holes: 1, sum holes: 4 */
        /* padding: 4 */
        /* last cacheline: 32 bytes */
};
…

Это должно быть намного приятнее для анализа, чем прямая C.

5 голосов
/ 12 января 2010

Регулярные выражения будут отлично работать примерно в 90% случаев, а затем будут вызывать бесконечные головные боли для оставшихся 10%.

Головные боли случаются в тех случаях, когда код C содержит синтаксис, о котором вы не задумывались при написании своих регулярных выражений. Затем вы возвращаетесь и понимаете, что C не может быть проанализирован регулярными выражениями, и жизнь становится невеселой.

Попробуйте перевернуть его: определите свой собственный простой формат, который допускает меньше трюков, чем делает C, и сгенерируйте из файла как заголовочный файл C, так и код интерфейса Python:

define socketopts
    int16 port
    int32 ipv4address
    int32 flags

Тогда вы можете легко написать Python, чтобы преобразовать это в:

typedef struct {
    short port;
    int ipv4address;
    int flags;
} socketopts;

, а также для создания класса Python, который использует struct для упаковки / распаковки трех значений (возможно, два из них с прямым порядком байтов, а другой - с прямым порядком байтов, до вас).

3 голосов
/ 12 января 2010

Взгляните на Swig или SIP , который будет генерировать для вас код интерфейса, или использовать ctypes .

2 голосов
/ 12 января 2010

Вы смотрели на Swig ?

1 голос
/ 07 марта 2012

ctypes-codegen или ctypeslib (я думаю, то же самое) сгенерирует определения ctypes Structure (я полагаю, также и другие вещи, но я только пробовал структуры) при разборе заголовочные файлы с использованием GCCXML. Он больше не поддерживается, но, вероятно, будет работать в некоторых случаях.

1 голос
/ 13 января 2010

Я довольно успешно использовал GCCXML в довольно крупных проектах. Вы получаете XML-представление кода C (включая структуры), которое вы можете постобработать с помощью простого Python.

0 голосов
/ 12 января 2010

Один мой друг для этой задачи сделал C-parser, который он использует с cog.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...