main.cpp
#include <iostream>
#include <Python.h>
#include "someMagic.h"
int main(int argc, char *argv[]) {
std::cout << "Hello, World!" << std::endl;
Py_Initialize();
printf("%d",great_function_from_python(1));
Py_Finalize();
return 0;
}
三步:
- 启动Python:Py_Initialize();
- 调用自己的Python程序
- 关闭Python:Py_Finalize();
someMagic.cpp
#include "someMagic.h"
#include <Python.h>
#include <iostream>
int great_function_from_python(int a) {
int res;
PyObject *pModule,*pFunc;
PyObject *pArgs, *pValue;
/* import */
PyRun_SimpleString("import sys");
PyRun_SimpleString("sys.path.append('./')");
pModule = PyImport_Import(PyUnicode_FromString("hello"));
if (pModule == nullptr)
{
PyErr_Print();
std::exit(1);
}
/* great_module.great_function */
pFunc = PyObject_GetAttrString(pModule, "great_function");
/* build args */
pArgs = PyTuple_New(1);
PyTuple_SetItem(pArgs,0, PyLong_FromLong(a));
/* call */
pValue = PyObject_CallObject(pFunc, pArgs);
res = PyLong_AsLong(pValue);
return res;
}
自己的python程序初始化:
- 导入模块:
-
PyRun_SimpleString("import sys"); PyRun_SimpleString("sys.path.append('./')");
用这两句为寻找模块时添加路径,好像Clion加不加都不影响
-
pModule = PyImport_Import(PyUnicode_FromString("hello")); if (pModule == nullptr) { PyErr_Print(); std::exit(1); }
本来只有第一句,而且教程里面的方法已经被弃用了,就写成了: pModule = PyImport_Import(PyBytes_FromString("hello"));死活跑不起来,上Stackoverflow找打了:导入模块为NULL,加上了if判断才知道原来参数传错了,就改成了PyUnicode...
-
- 连接函数:
- pFunc = PyObject_GetAttrString(pModule, "great_function");没什么好说的
- 创建变量表:
-
pArgs = PyTuple_New(1); PyTuple_SetItem(pArgs,0, PyLong_FromLong(a));
PyTuple_GetItem可以返回某个位置的值,功能类似:a = myList[1]
-
- 调用函数:
-
pValue = PyObject_CallObject(pFunc, pArgs); res = PyLong_AsLong(pValue);
都需要用一些函数来进行C++与Python直接数据类型的转换
-
就像知乎教程上说的:
从上述代码可以窥见Python内部运行的方式:
- 所有Python元素,module、function、tuple、string等等,实际上都是PyObject。C语言里操纵它们,一律使用PyObject *。
- Python的类型与C语言类型可以相互转换。Python类型XXX转换为C语言类型YYY要使用PyXXX_AsYYY函数;C类型YYY转换为Python类型XXX要使用PyXXX_FromYYY函数。
- 也可以创建Python类型的变量,使用PyXXX_New可以创建类型为XXX的变量。
- 若a是Tuple,则a[i] = b对应于 PyTuple_SetItem(a,i,b),有理由相信还有一个函数PyTuple_GetItem完成取得某一项的值。
- 不仅Python语言很优雅,Python的库函数API也非常优雅。
hello.py
import sys
def great_function(a):
print(sys.path)
return a + 1