本文参考自:https://zongxp.blog.csdn.net/article/details/115690713 , https://blog.csdn.net/qq_31342997/article/details/88368420
c++ 调用 python ,本质上是在 c++ 中启动了一个 python 解释器,由解释器对 python 相关的代码进行执行,执行完毕后释放资源,达到调用目的。
1 调用流程
————————————————
c++ 调用python的流程:
1)初始化Python调用环境
2)加载对应的Python模块
3)加载对应的Python函数
4)将参数转化为Python元组类型
5)调用Python函数并传入参数元组
6)获取返回值
7)根据Python函数的定义解析返回值
————————————————
1.安装python
2.设置附加包含目录:
D:Program FilesPythonPython38include
3.设置附加库目录:
D:Program FilesPythonPython38libs
4.设置附加库:
_tkinter.lib
python3.lib
python38.lib
下边的代码 main.cpp 包含了调用流程内容
#include <Python.h> #include <iostream> using namespace std; int main(int argc, char *argv[]) { // 初始化python解释器.C/C++中调用Python之前必须先初始化解释器 Py_Initialize(); // 执行一个简单的执行python脚本命令 PyRun_SimpleString("print('hello world') "); // 撤销Py_Initialize()和随后使用Python/C API函数进行的所有初始化 Py_Finalize(); cin.get(); return (0); }
效果:
2 无参函数调用
在上边的例子中,我们介绍了在 c++ 中执行 python 语句的方法,简单的完成了一个 print 功能。而实际使用时,我们需要调用 python 模块以及模块中的函数,并且有可能需要参数传递以及返回值获取。我们首先先实现一个简单的无参数传递的函数调用功能。
#include <Python.h> #include <iostream> using namespace std; int main(int argc, char *argv[]) { // 1、初始化python接口 Py_Initialize(); if (!Py_IsInitialized()) { cout << "python 初始化失败!" << endl; cin.get(); return 0; } // 2、初始化python系统文件路径,保证可以访问到 .py文件 PyRun_SimpleString("import sys"); PyRun_SimpleString("sys.path.append('./script')");//exe文件旁边有script文件夹,文件夹中有sayhello.py // 3、调用python文件名,不用写后缀 PyObject* pModule = PyImport_ImportModule("sayhello"); if (pModule == NULL) { cout << "模块不存在!" << endl; cin.get(); return 1; } // 4、调用函数 PyObject* pFunc = PyObject_GetAttrString(pModule, "say"); if (!pFunc || !PyCallable_Check(pFunc)) { cout << "not found function add_num" << endl; cin.get(); return 0; } // PyObject_CallObject(pFunc, NULL); // 5、结束python接口初始化 Py_Finalize(); cin.get(); return 0; }
python 脚本内容
def say(): print("hello")
运行结果:
3 有参函数调用
代码:
#include<Python.h> #include <iostream> using namespace std; int main(int argc, char *argv[]) { Py_Initialize(); //1、初始化python接口 //初始化使用的变量 PyObject* pModule = NULL; PyObject* pFunc = NULL; PyObject* pName = NULL; //2、初始化python系统文件路径,保证可以访问到 .py文件 PyRun_SimpleString("import sys"); PyRun_SimpleString("sys.path.append('./')");//与exe文件并列有个myadd.py //3、调用python文件名。当前的测试python文件名是 myadd.py // 在使用这个函数的时候,只需要写文件的名称就可以了。不用写后缀。 pModule = PyImport_ImportModule("myadd"); //4、调用函数 pFunc = PyObject_GetAttrString(pModule, "AdditionFc"); //5、给python传参数 // 函数调用的参数传递均是以元组的形式打包的,2表示参数个数 // 如果AdditionFc中只有一个参数时,写1就可以了 PyObject* pArgs = PyTuple_New(2); // 0:第一个参数,传入 int 类型的值 2 PyTuple_SetItem(pArgs, 0, Py_BuildValue("i", 2)); // 1:第二个参数,传入 int 类型的值 4 PyTuple_SetItem(pArgs, 1, Py_BuildValue("i", 4)); // 6、使用C++的python接口调用该函数 PyObject* pReturn = PyEval_CallObject(pFunc, pArgs); // 7、接收python计算好的返回值 int nResult; // i表示转换成int型变量。 // 在这里,最需要注意的是:PyArg_Parse的最后一个参数,必须加上“&”符号 PyArg_Parse(pReturn, "i", &nResult); cout << "return result is " << nResult << endl; //8、结束python接口初始化 Py_Finalize(); cin.get(); return 0; }
python 脚本内容
def AdditionFc(a, b): print("Now is in python module") print("{} + {} = {}".format(a, b, a+b)) return a + b
结果: