之前和大家介紹過在C/C++中嵌入Python,本次和大家分享下使用C/C++擴充套件Python內建模組的方法。
被擴展出來的新模組可以做兩件無法直接在Python中完成的事情:一可以實現新的內建物件型別,二則可以呼叫C庫函式和一些其他的系統呼叫。
使用平臺:ubuntu14。04、python3。5、Qt 5。5。1
下面藉助Qt建立一個叫libpy3extend 的Python內建模組,它可以做一個簡單的加法操作,還可以返回一個自定義的資料型別。呼叫形式如下:
import libpy3extend
libpy3extend。extend_add(1,99)
ibpy3extend。extend_str()
先使用Qt建一個生成庫的工程,之後按照步驟進行操作即可。
1。 extend。cpp檔案首先是包含所用到的標頭檔案:
#include
#include
2。 向extend。cpp模組檔案中新增C函式,該函式在執行libpy3extend。extend_add(1,99) 時被呼叫。C函式總是有兩個引數,通常命名為self和args。
static PyObject *extend_add(PyObject *self, PyObject *args){ (void)(self); PyObject *pArgs = NULL;
int result = 0;int arg1 = 0;int arg2 = 0;
if (!PyArg_ParseTuple(args, “ii”,&arg1,&arg2)) {std::cerr << “parameters error” << std::endl; Py_INCREF(Py_None); pArgs = Py_None; }else { result = arg1 + arg2; pArgs = Py_BuildValue(“i”, result); }
return pArgs;}
args引數是一個元組物件,使用PyArg_ParseTuple()函式來解析,解析規則可參考python文件
https://docs。python。org/3/c-api/arg。html#arg-parsing
3。 建立模組方法表並在表中列出函式名稱和地址。
static PyMethodDef extendMethods[] = {//extend add {“extend_add”, extend_add, METH_VARARGS, NULL}, {“extend_str”, extend_str, METH_VARARGS, NULL}, {NULL, NULL, 0, NULL}};
METH_VARARGS表示該函式希望引數傳遞為元組資料以使用PyArg_ParseTuple()函式來解析。
4。 在模組定義結構中引用方法表
staticstructPyModuleDefextendMoudle = { PyModuleDef_HEAD_INIT,“py3extend”, /* name of module */NULL, /* module documentation, may be NULL */-1, /* size of per-interpreter state of the module, or -1 if the module keeps state in global variables。 */ extendMethods,
NULL,NULL,NULL,NULL };
5。 將剛才定義的結構傳遞給模組初始化函式中的直譯器。
注意:必須命名初始化函式PyInit_name(),其中name是模組的名稱。我這裡模組名稱是py3extend,但是由於生成的是庫檔案,會自動加上lib字首,所以這 裡模組名稱是libpy3extend,不是該名稱會報
ImportError: dynamic module does not define module export function (PyInit_libpy3extend)
這個錯誤。
PyMODINIT_FUNC PyInit_libpy3extend(void){//to use thread in extend moudle// if (!PyEval_ThreadsInitialized()) {// PyEval_InitThreads();// }
return PyModule_Create(&extendMoudle);}
到這裡就可以藉助Qt生成庫檔案了,如果不知道怎麼使用Qt生成庫檔案可以參考Qt建立共享庫該文章。
接下來是如何使用庫檔案。將庫檔案與python測試檔案放到同一目錄下,即可執行測試。如圖:
如需要完成工程可在公眾號後臺留言。
歡迎交流: