C++如何调用简单的python程序
作者:Ai_Taoism
这篇文章主要介绍了C++如何调用简单的python程序问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
一、基本环境的搭建
首先,用vs创建一个win32的控制台应用程序项目(vs2017及以上怎么创建百度一下就知道了)。
然后配置好python的环境变量(把include文件夹加到包含目录,libs文件夹加到库目录,最好还把include文件夹加到附加包含目录)。
如下图所示:
最后,把python36.libs文件加到依赖项(如果是debug编译,要重命名python36.libs为python36_d.libs,然后加到依赖项)
如下图所示。
二、直接在C++里面调用执行python语句
搭建好一中的环境之后,在源文件里面新建一个cpp文件,cpp里面的代码如下。
代码很简单,应该一看就懂了吧。
#include <Python.h> #include <stdio.h> #include <iostream> using namespace std; int main() { //***python调用***// //直接在C++里面执行python语句 void usePythonWorld(); usePythonWorld(); system("pause"); } void usePythonWorld()//调用无参数函数 { //初始化python模块:用来分配python解释器所使用的全局资源 Py_SetPath(L"D:/chengxuanzhuang/anaconda/envs/python3.6/Lib"); Py_Initialize(); if (!Py_IsInitialized())// 检查初始化是否成功 { cout << "初始化失败" << endl; Py_Finalize(); } //直接调用python语句(没有成功) PyRun_SimpleString("print('in python'\n)"); Py_Finalize(); }
需要注意的地方是,在使用PyRun_SimpleString之前,一定要使用 Py_Initialize()初始化Python。
三、调用python脚本文件里面的定义函数
调用不含参数的函数
搭建好一中的环境之后,在源文件里面新建一个cpp文件,cpp里面的代码如下。
代码很简单,应该一看就懂了吧。
#include <Python.h> #include <stdio.h> #include <iostream> using namespace std; int main() { //***python调用***// //调用无参数python函数 bool InvokeNonParasFuncByAPI(string module, string func); InvokeNonParasFuncByAPI("PythonGreet", "Hello"); system("pause"); } bool InvokeNonParasFuncByAPI(string module, string func) { Py_SetPath(L"D:/chengxuanzhuang/anaconda/envs/python3.6/Lib"); Py_Initialize(); if (!Py_IsInitialized()) { return false; } try { //将当前目录切换到python脚本放置的目录,因为初始化到了python的全局资源下,所以只能只用python语句 PyRun_SimpleString("import sys\n"); PyRun_SimpleString("sys.path.append('./')");//这个一个简单的执行python脚本命令的函数,由于路径是'./',所以python脚本要放在这个项目的根目录 //调用pyhton脚本 PyObject* moduleName = PyUnicode_FromString(module.c_str()); PyObject* pModule = PyImport_Import(moduleName); if (!pModule) { cout << "Import Module Failed" << endl; return false; } PyObject* pFunc = PyObject_GetAttrString(pModule, func.c_str());//调用脚本里面的函数 if (!pFunc || !PyCallable_Check(pFunc)) //这里面的这个函数是用来判断方法是否有效 { cout << "Get Function Failed!" << endl; return false; } PyObject* pResult = PyObject_CallObject(pFunc, nullptr);//使用python脚本里面的函数 if (!pResult) { cout << "Get Result of Function Failed!" << endl; return false; } } catch (...) { PyErr_Print(); //如果出错会打印出错误 PyErr_Clear(); Py_Finalize(); return false; } Py_Finalize(); return true; }
调用含一个参数的函数
搭建好一中的环境之后,在源文件里面新建一个cpp文件,cpp里面的代码如下。
代码很简单,应该一看就懂了吧。
其中的demo_test是python脚本文件名,注意不是demo_test.py。最后把这个python脚本文件和cpp文件放在同一个文件夹下(注意不是放在源文件里,而是找到cpp文件所在的文件夹,放到这个文件夹里。
如下。如果是在项目里直接创建的python文件,会自动存放到这个文件夹下)
不出意外,就可以运行这个cpp文件了。
调用含多个参数的函数
搭建好一中的环境之后,在源文件里面新建一个cpp文件,cpp里面的代码如下。
代码很简单,应该一看就懂了吧。
#include <Python.h> #include <stdio.h> #include <iostream> #include <vector> using namespace std; int main() { //***python调用***// //调用含参数的python函数 vector<int> paras; paras.push_back(3); paras.push_back(4); bool InvokeFuncbyAPI(string module, string func, vector<int> paras); InvokeFuncbyAPI("PythonCalc", "Add",paras); system("pause"); } bool InvokeFuncbyAPI(string module, string func,vector<int> paras) { Py_SetPath(L"D:/chengxuanzhuang/anaconda/envs/python3.6/Lib"); Py_Initialize(); if (!Py_IsInitialized()) { return false; } try { //将当前目录切换到python脚本放置的目录,因为初始化到了python的全局资源下,所以只能只用python语句 PyRun_SimpleString("import sys\n"); PyRun_SimpleString("sys.path.append('./')");//这个一个简单的执行python脚本命令的函数,由于路径是'./',所以python脚本要放在这个项目的根目录 //调用pyhton脚本 PyObject* moduleName = PyUnicode_FromString(module.c_str()); PyObject* pModule = PyImport_Import(moduleName); if (!pModule) { cout << "Import Module Failed" << endl; return false; } PyObject* pFunc = PyObject_GetAttrString(pModule, func.c_str());//调用脚本里面的函数 if (!pFunc || !PyCallable_Check(pFunc)) //这里面的这个函数是用来判断方法是否有效 { cout << "Get Function Failed!" << endl; return false; } PyObject* pResult = nullptr; //创建一个获取结果的python数据结构 PyObject* args = PyTuple_New((int)paras.size());//建立一个存放入参的python数据结构 for (int i = 0; i < (int)paras.size(); i++) { PyTuple_SetItem(args, i, PyLong_FromLong(paras[i])); //将C++的参数转化为python的参数 } pResult = PyObject_CallObject(pFunc, args); if (!pResult) { cout << "Get Result of Function Failed!" << endl; return false; } cout << "Result = " << PyLong_AsLong(pResult) << "by python api" << endl; } catch (...) { PyErr_Print();//如果出错会打印出错误 PyErr_Clear(); Py_Finalize(); return false; } Py_Finalize(); return true; }
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。