C++ 调用 Python (Python官方提供的实现方式)
首先有一个Python函数
def PythonFunc(number):
return number + 10;
我们期望在C++中使用的时候应该是类似下面这种
int UsePythonFunction(int num){
int result;
///do something
return result;
}
这个do something 中就需要以下步骤:
- 要将python模块import进来
- 然后就应该把需要调用的Python函数对象创建出来
- 把C++参数转换成对应的Python中的参数
- 执行函数
- 将结果从Python对象转换成c++对象
根据以上的步骤可以写出下面的代码
int UsePythonFunction(int num){
Py_Initialize();
///improt 对应模块 我这边的模块名字是python_function
PyObject *pModule = PyImport_Import(PyString_FromString("python_function"));
///将对应的函数对象创建出来
PyObject *pFunc = PyObject_GetAttrString(pModule, "PythonFunc");、
///这边是将参数转成Python版本
PyObject *args = PyTuple_New(1);
PyTuple_SetItem(args, 0, PyInt_FromLong(num));
///执行函数
PyObject *res = PyObject_CallObject(pFunc, args);
///将结果转成C++版本
int result = PyInt_AsLong(res);
Py_Finalize();
return result;
}
- 从上面的代码可以看出,在C++ 中操纵Python对象的时候都是通过PyObject*
- C++中XXX类型转换成Python中YYY类型的时候,需要使用PyYYY_FromXXX,同理,从Python中YYY类型转成C++中XXX类型的时候,需要使用PyYYY_ASXXX
- 创建Python元组的时候需要通过调用 PyTuple_New
- 对元组赋值使用PyTuple_SetItem、
在Linux下使用下面命令进行编译链接。
gcc Test.cpp -o Test -I/usr/include/python2.7/ -lpython2.7
Python调用 C++ (Python官方提供的实现方式)
和之前的例子相同
这次我有一个C++的函数 在c_function_module.cpp中
int CFunction(int a) {
return a -= 10;
}
我想在Python以下方式来调用它
from c_function_module import CFunction
print CFunction(2);
这时候Python对象转C++对象的代码还是保存在C++文件中
///c_function_module.cpp
#include <Python.h>
int CFunction(int a) {
return a -= 10;
}
static PyObject * _CFunction(PyObject *self, PyObject *args)
{
int _args;
int res;
if (!PyArg_ParseTuple(args, "i", &_args))
return NULL;
res = CFunction(_args);
return PyLong_FromLong(res);
}
static PyMethodDef CFunctionModuleMethods[] = {
{
"CFunction",
_CFunction,
METH_VARARGS,
""
},
{NULL, NULL, 0, NULL}
};
PyMODINIT_FUNC initc_function_module(void) {
(void) Py_InitModule("c_function_module", CFunctionModuleMethods);
}
解释下上面的一些东西:
- CFunction 就是我们实际要调用的函数
- _CFunction 成为包裹函数,它负责将Python对象转成C++对象,并调用对应函数,将结果转回Python 对象,PyArg_ParseTuple是将args按照后面的规则将参数转成_agrs,“i” 代表这第一个参数为Int,“is” 代表第一个参数为Int,第二个参数为字符串
- CFunctionModuleMethods 成为导出表,这个表的每一项有4个参数:
在Python中需要调用的函数的名字
包裹函数
METH_VARARGS 代表变长参数
函数说明
导出表以{NULL, NULL, 0, NULL}结束
- initc_function_module 这个是唯一 一个名字不能乱取的函数,这个函数名是init 加上 module名字构成,这边我的module名称为“c_function_module”,所以我的函数名字就是initc_function_module,
在linux中通过以下命令编译c++文件
gcc -fPIC -shared c_function_module.cpp -o c_function_module.so -I/usr/include/python2.7/ -lpython2.7
然后通过之前希望的方式在Python 中调用函数
还有一点,不能直接import整个模块,只能from模块import对应函数