如何将.h文件中的常量导入Python模块

4 投票
5 回答
4980 浏览
提问于 2025-04-15 17:15

有什么推荐的方法可以将一堆在C语言(不是C++,就是普通的C).h文件中定义的常量导入到Python模块中,以便在项目的Python部分使用。在这个项目中,我们使用了多种语言,而在Perl中,我可以通过使用h2xs工具生成.pm模块来实现这种导入。

常量的定义看起来像这样:

#define FOO 1
enum {
    BAR,
    BAZ
}; 

等等。

C语言风格的注释也存在,需要妥善处理。

5 个回答

0

我建议你反过来做,如果可以的话:把你所有的常量放在一个Python字典或者模块里,然后用Python自动生成.h文件。这样会简单很多,简单很多。

1

我之前也遇到过类似的情况,最后我做了一些奇怪但非常可靠的事情。处理值可能被定义的各种情况是很棘手的……比如,你需要处理

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

(这真的很麻烦,没人应该这样做……)

最后,我的构建过程里有一个perl脚本,它会解析头文件中的所有枚举和定义,然后生成一个.c文件,这个文件只包含了一堆打印语句,打印每个定义的实际值。这个文件被编译并执行,输出的结果用来生成下一个源文件(在我的情况下是Java)。

这样做确保我得到了正确的值,因为我使用了C语言的预处理器和编译器来得到答案。

6

我最近使用了pyparsing这个库来查找枚举常量。下面是我用的代码,还有一个示例字符串和输出结果。注意,它还可以处理注释和被注释掉的部分。如果稍微修改一下,就可以把常量放进一个字典里。

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

撰写回答