一、本文接續Extending Python with C/ C++ (一) 的內容進階的說明下列三項內容:
1-1、如何在Python中使用自訂的方法(Method)當成Callback function的方法來呼叫C函式。
1-2、如何提供自訂的Python物件及建立該物件內的方法(Method)
1-3、如何以繼承的方式自訂新的Python物件及建立該物件內的方法(Method)
二、建立一個提供給Python使用的C語言函式並包含Callback function的參數:
2-1、首先是使用PyArg_ParseTuple來接收由Python所傳遞的方法(Method)物件及參數。
EX. PyArg_ParseTuple(args,"Oi",&Pycallback,&waittime );
2-2、使用PyCallback_Check函式來判斷傳遞的物件是否為可呼叫的物件。
2-3、當使用者傳遞的物件為不可呼叫的物件時,可以使用PyErr_SetString的函式。
2-4、使用PyEval_CallObject函式來執行由Python傳遞的方法(Method)物件。
三、如何提供自訂的Python物件及建立該物件內的方法(Method):
3-1、建立PyTypeObject物件並透過設定該物件的屬性內容來初始化物件的功能及相關的能力,
不同的版本設定ob_size的欄位方式有所不同:
PYTHON27 :
PyObject_HEAD_INIT(NULL),
0,
PYTHON31:
PyVarObject_HEAD_INIT(NULL,0),
3-2、建立PyMemberDef 靜態陣列,該靜態陣列主要的功能是例舉自訂物件的屬性,並將該陣列
設定於PyTypeObject物件中的tp_members(29 or 30)欄位。
3-3、建立PyMethodDef 靜態陣列,該靜態陣列主要的功能是提供自訂物件的方法(Method),並將
該陣列設定於PyTypeObject物件中的tp_methods(30 or 31)欄位。
3-4、建立Python專用的C 語言 typedef struct,當使用者新增物件時透過type->tp_alloc函式分
配記憶體並回傳此結構指標;當使用Python專用的C語言typedef struct時必須先include
<structmember.h> 並且在宣告struct的內容中必須加入PyObject_HEAD宣告:
EX. type struct{
PyObject_HEAD
…………
}basetype;
3-5、建立create function並於函式中使用PyType_Ready函式來載入PyTypeObject物件,而當
Module在初始化成功後,才可呼叫此create function。
四、如何以繼承的方式自訂新的Python物件及建立該物件內的方法(Method):
4-1、以繼承的方式來建立自訂的Python物件的基本步驟與上述第三項的內容相同。
4-2、在建立PyTypeObject物件時,必須在tp_base中設定它的基礎物件(父物件)。
4-3、以繼承的方式來建立PyTypeObject物件時不能設定tp_new函式於物件的tp_new欄位(38 or 39)。
4-4、以繼承的方式來建立Python專用的C 語言typedef struct,與上述3-4唯一不同的是不需要在
struct中宣告PyObject_HEAD而是改成宣告要繼承的基礎struct:
EX. type struct {
basetype bt;
…………
}inherittype;
4-5、初始化繼承物件時必須先在初始化函式中成功執行基礎物件的初始化,才可以繼續初始化函式。
五、範例說明:
將newtype.pyd Module複製至Pythonx.x\DLLs下,該Module包含兩個物件和
一個Callback方法(method):
5-1、Callback Function 一
newtype.pyd:
在module中宣告callback函式,主要的功能是接收由Python所傳遞的方法(method)和
整數(int)參數並依數值為時間區間來執行由Pthon所傳遞的方法(Method)。
usenewtype.py:
在Python中建立一個新的Thread並在Thread中執行newtype module中的callback方法
(method);另外在parent threading中每隔一秒累加列印次數。
5-2、BaseType object 一
newtype.pyd: 說明如何建立自訂的物件。
usenewtype.py: 說明如何在pythone中使用自訂的物件。
5-3、InheritType object 一
newtype.pyd: 說明如何建立以繼承的方式來自訂物件。
usenewtype.py: 說明如何在pythone中使用以繼承的方式產生的自訂物件。
PS: 本文範例有分成支援Python2.7和Python3.1,因此在不同的Python版本中必須引用
不同版本的Module。
Download: NewType.zip
Result:
Eclipse with C:
1、設定Include file 和Libraries file(Path):
Project -> Properties -> C/C++build -> Settings -> Tools Settings ->
Include and Libraries.
2、設定輸出的檔案類型:
Project->Properties->C/C++build -> Settings-> Build Artifact ->
Artifact Type: Shared Library
Artifact extension: pyd
Eclipse with Python:
留言列表