2011-04-18 56 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