Как импортировать константы из файла .h в модуль Python - PullRequest
3 голосов
/ 21 декабря 2009

Каков рекомендуемый способ импорта набора констант, определенных в файле c (не c ++, просто старый c) .h, в модуль python, чтобы его можно было использовать в части проекта python. В проекте мы используем смесь языков, и в perl я могу сделать это с помощью утилиты h2xs для генерации модуля .pm.

Определение константы выглядит как

#define FOO 1
enum {
    BAR,
    BAZ
}; 

и т.д.

Комментарии в стиле C также представлены и должны быть обработаны должным образом.

Ответы [ 4 ]

5 голосов
/ 22 декабря 2009

Я недавно использовал библиотеку pyparsing для поиска констант enum. Вот оно, вместе с образцом строки и полученным результатом. Обратите внимание, что он также обрабатывает комментарии и закомментированные разделы. С небольшой модификацией он может заполнить константы в словаре.

from pyparsing import *

sample = '''
    stuff before

    enum hello {
        Zero,
        One,
        Two,
        Three,
        Five=5,
        Six,
        Ten=10
    }

    in the middle

    enum blah
    {
        alpha, // blah
        beta,  /* blah blah
        gamma = 10 , */
        zeta = 50
    }

    at the end
    '''

# syntax we don't want to see in the final parse tree
_lcurl = Suppress('{')
_rcurl = Suppress('}')
_equal = Suppress('=')
_comma = Suppress(',')
_enum = Suppress('enum')

identifier = Word(alphas,alphanums+'_')
integer = Word(nums)

enumValue = Group(identifier('name') + Optional(_equal + integer('value')))
enumList = Group(enumValue + ZeroOrMore(_comma + enumValue))
enum = _enum + identifier('enum') + _lcurl + enumList('list') + _rcurl

enum.ignore(cppStyleComment)

for item,start,stop in enum.scanString(sample):
    id = 0
    for entry in item.list:
        if entry.value != '':
            id = int(entry.value)
        print '%s_%s = %d' % (item.enum.upper(),entry.name.upper(),id)
        id += 1

ВЫВОД:

HELLO_ZERO = 0
HELLO_ONE = 1
HELLO_TWO = 2
HELLO_THREE = 3
HELLO_FIVE = 5
HELLO_SIX = 6
HELLO_TEN = 10
BLAH_ALPHA = 0
BLAH_BETA = 1
BLAH_ZETA = 50
1 голос
/ 21 декабря 2009

Мне когда-то приходилось делать нечто подобное, и в конце концов я сделал что-то странное, но очень надежное. Разобраться во всех возможностях определения значений сложно, например, вам нужно обработать

#include "someotherfile.h"
enum NewEnum {
   A = -5,
   B = SOME_OTHER_ENUM, 
   C,
   D = 3
};

(что действительно противно, и никто никогда не должен делать ...)

В итоге частью моего процесса сборки был сценарий perl, который анализировал заголовочный файл для всех перечислений и определений, а затем создавал .c-файл, который включал заголовок и представлял собой не что иное, как кучу операторов print фактическое значение для каждого определения. Этот файл был скомпилирован и выполнен, а выходные данные использовались для создания следующего исходного файла (в моем случае, Java).

Это гарантировало, что я получил правильные значения, так как я использовал препроцессор C и компилятор для получения ответов.

0 голосов
/ 02 марта 2010

Создайте скрипт / программу, которая вызывается из make и создает необходимый файл python. Если вам нужен только #define и enum, написать его не составит труда. Затем не забудьте включить этот файл python в систему управления версиями, так как вы хотите, чтобы процесс сборки каждый раз вызывал перегенерирование файла.

0 голосов
/ 30 декабря 2009

Я бы предложил, если это возможно, наоборот: определите все свои константы в файле или модуле Python и автоматически сгенерируйте .h в Python. Это будет намного, намного проще.

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