之前和大家介绍过在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. 在模块定义结构中引用方法表
static struct PyModuleDef extendMoudle =
{
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 前缀,所以这 里模块名称是 lib py3extend ,不是该名称会报
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测试文件放到同一目录下,即可运行测试。如图:
如需要完成工程可在公众号后台留言。
欢迎交流: