10

我有一个 C 文件,其中包含一堆我想从 python 引用的位的#defines。它们足够多,我宁愿不将它们复制到我的 python 代码中,而是有一种可接受的方法可以直接从 python 引用它们?

注意:我知道我可以打开头文件并解析它,这很简单,但如果有更 Pythonic 的方式,我想使用它。

编辑:

这些是非常简单的#defines,用于定义掩码中位的含义,例如:

#define FOO_A 0x3
#define FOO_B 0x5
4

5 回答 5

7

您可能对在 Python 源代码压缩包目录中h2py.py找到的脚本感到幸运。Tools/scripts虽然它不能处理复杂的预处理器宏,但它可能足以满足您的需求。

以下是脚本顶部的功能描述:

阅读#define 并翻译成 Python 代码。处理#include 语句。使用一个参数处理#define 宏。任何无法识别或无法转换为有效 Python 的内容都会被忽略。

没有文件名参数,充当过滤器。如果给出了一个或多个文件名,则输出将写入本地目录中的相应文件名,翻译为全大写,扩展名替换为“.py”。

通过传递一个或多个“-i regular_expression”形式的选项,您可以指定要忽略的附加字符串。这很有用,例如忽略对 u_long 的强制转换:只需指定“-i '(u_long)'”。

于 2012-08-28T04:38:10.270 回答
7

在假设 C .h 文件仅包含 #defines (因此没有外部链接)的假设下运行,则以下内容适用于 swig 2.0(http://www.swig.org/)和 python 2.7(经过测试)。假设包含刚刚定义的文件名为 just_defines.h,如上所示:

#define FOO_A 0x3
#define FOO_B 0x5

然后:

swig -python -module just just_defines.h ## generates just_defines.py and just_defines_wrap.c
gcc -c -fpic just_defines_wrap.c -I/usr/include/python2.7 -I. ## creates just_defines_wrap.o
gcc -shared just_defines_wrap.o -o _just.so ## create _just.so, goes with just_defines.py

用法:

$ python 
Python 2.7.3 (default, Aug  1 2012, 05:16:07) 
[GCC 4.6.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import just
>>> dir(just)
['FOO_A', 'FOO_B', '__builtins__', '__doc__', '__file__', '__name__', '__package__', '_just', '_newclass', '_object', '_swig_getattr', '_swig_property', '_swig_repr', '_swig_setattr', '_swig_setattr_nondynamic']
>>> just.FOO_A
3
>>> just.FOO_B
5
>>> 

如果 .h 文件还包含入口点,那么您需要链接到某个库(或更多)以解析这些入口点。这使解决方案变得更加复杂,因为您可能必须寻找正确的库。但是对于“只定义案例”,您不必担心这一点。

于 2012-08-27T18:53:37.157 回答
1

#defines 是宏,在 C 编译器的预处理器之外没有任何意义。因此,它们是世界各地多语言程序员的祸根。(例如,请参阅这个 Ada 问题:在两周前为 linux 内核中的模块设置许可证)。

如果没有通过 C 预处理器运行您的源代码,确实没有很好的方法来处理它们。我通常只是弄清楚他们评估的内容(在复杂的情况下,通常没有比实际编译和运行该死的代码更好的方法来做到这一点!),并将该值硬编码到我的程序中。

(其中一个)令人讨厌的部分是 C 编码器认为 C 预处理器是一个非常简单的小东西,他们经常使用它甚至没有考虑过。结果,他们往往会惊讶于它会给互操作性带来很大的问题,而我们可以相当容易地处理 C 给我们带来的大多数其他问题。

在上面显示的简单案例中,到目前为止,最简单的处理方法是将相同的两个值编码为 Python 程序中某处的常量。如果跟上变化很重要,那么编写一个 Python 程序将这些值从文件中解析出来可能不会太麻烦。但是,您必须意识到您的 C 代码只会在编译时重新评估这些值,而您的 python 程序会在它运行时执行它(因此可能应该只在 C 代码也被编译时运行)。

于 2012-08-27T18:29:36.787 回答
1

如果您正在编写扩展模块,请使用http://docs.python.org/3/c-api/module.html#PyModule_AddIntMacro

于 2014-03-04T22:12:45.797 回答
0

我几乎遇到了同样的问题,所以写了一个 Python 脚本来解析 C 文件。它旨在重命名以匹配您的 c 文件(但使用 .py 而不是 .h)并作为 Python 模块导入。

代码:https ://gist.github.com/camlee/3bf869a5bf39ac5954fdaabbe6a3f437

例子:

配置.h

#define VERBOSE 3
#define DEBUG 1
#ifdef DEBUG
    #define DEBUG_FILE "debug.log"
#else
    #define NOT_DEBUGGING 1
#endif

从 Python 中使用:

>>> import configuration
>>> print("The verbosity level is %s" % configuration.VERBOSE)
The verbosity level is 3
>>> configuration.DEBUG_FILE
'"debug.log"'
>>> configuration.NOT_DEBUGGING is None
True
于 2016-09-13T05:51:06.070 回答