Подтвердить что ты не робот

Извлечь поля структуры C

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

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

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

4b9b3361

Ответ 1

Если вы скомпилируете свой код 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 */
};
…

Это должно быть намного лучше, чем синтаксический анализ.

Ответ 2

Регулярные выражения будут работать отлично в 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 для упаковки/распаковки трех значений (возможно, двух из них - big-endian и другого native-endian, до вас).

Ответ 3

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

Ответ 4

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

Ответ 5

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

Ответ 6

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

Ответ 7

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