2011-04-18 86 views
19

我想打the integer constants (ACTIVE_TAG, etc) defined here如何在Cython模块中将#defined C值暴露给Python?

//island management, m_activationState1 
#define ACTIVE_TAG 1 
#define ISLAND_SLEEPING 2 
#define WANTS_DEACTIVATION 3 
#define DISABLE_DEACTIVATION 4 
#define DISABLE_SIMULATION 5 

可作为用Cython定义模块我工作的正常属性,这样Python应用程序代码可以访问它们(他们在传递到包裹的API是哪些根据它们定义)。

我已经看过用cdef作为整数或枚举来定义这些方法,但这两种方法都没有将值绑定到Cython模块中的属性。还有什么其他选择?

回答

20

这里有一种方法,其中,虽然看似繁琐,可以实用任何给定的.h文件作为输入自动化:

步骤1.获取你想要的所有常量到一个文件,说bulletdefs.h,它具有#defines但与领先的下划线,如:

#define _ACTIVE_TAG 1 
#define _ISLAND_SLEEPING 2 
#define _WANTS_DEACTIVATION 3 
#define _DISABLE_DEACTIVATION 4 
#define _DISABLE_SIMULATION 5 

步骤2.将部分转化为你的模块PYX文件,说bullet.pyx

cdef extern from "bulletdefs.h": 
    cdef int _ACTIVE_TAG 
    cdef int _ISLAND_SLEEPING 
    cdef int _WANTS_DEACTIVATION 
    cdef int _DISABLE_DEACTIVATION 
    cdef int _DISABLE_SIMULATION 

ACTIVE_TAG = _ACTIVE_TAG 
ISLAND_SLEEPING = _ISLAND_SLEEPING 
WANTS_DEACTIVATION = _WANTS_DEACTIVATION 
DISABLE_DEACTIVATION = _DISABLE_DEACTIVATION 
DISABLE_SIMULATION = _DISABLE_SIMULATION 

然后,当你编译你的模块,你应该得到预期的效果:

Python 2.7.1+ (r271:86832, Apr 11 2011, 18:05:24) 
[GCC 4.5.2] on linux2 
Type "help", "copyright", "credits" or "license" for more information. 
>>> import bullet 
>>> bullet.ACTIVE_TAG 
1 
>>> bullet.DISABLE_SIMULATION 
5 
>>> 
+15

谢谢。这是有效的,甚至还有一个可以采取的捷径(这是我之前陷入困境的地方)。我可以直接从bullet使用该定义,并通过执行诸如'cdef int _ACTIVE_TAG“ACTIVE_TAG”'的方式在Cython命名空间中对其进行重命名。引号中的名称是Cython在事物的C端查找的名称,左边的名称是它的值暴露给Python的名称。 – 2011-04-18 18:13:55

+1

这很整齐,谢谢你指出快捷方式! – 2011-04-18 18:52:29

+0

@ Jean-PaulCalderone我想你的意思是'cdef int ACTIVE_TAG“_ACTIVE_TAG”'。 – 2011-11-03 09:21:52