1、首先介绍下Python安装,登录https://www.python.org/downloads/,下载自己需要的版本下载进行安装,我下载的是3.7.3。安装需要注意,需要使用Debug版本进行编译的,需要在安装时勾对应选项:
2、安装完毕之后进行vs配置
(1)新建c++工程此处不做介绍。
(2)新建工程完毕,进行python路径配置。右键工程-属性:(此处我配置的是Debug、Win32平台,所以需要安装python_x86安装包,如果你想使用x64编译,必须安装Python_x64安装包,否则编译会报错,我安装了python两个版本,这两个版本是兼容的。)
(3)配置完毕可以开始进行编码:
1)建立python文件,文件名为PythonTest.py,python文件内容为:
def Test_add(a,b):
return a+b
2)在c++文件的 main函数中写入如下代码(也是在网上学习的,部分代码我有注释,程序仍可以正常运行):
//此处代码我进行注释,个人认为电脑安装python,设有系统环境变量,此处应该可以省略,但是如果部署电脑不安装python,应该需要进行配置,此处还未验证,后续会更新。
//CString PythonPath = _T("C:\Programs\Python37-32");
//Py_SetPythonHome(PythonPath);//配置python3的环境变量
Py_Initialize(); // 初始化
// 将Python工作路径切换到待调用模块所在目录,一定要保证路径名的正确性
CString path = _T("E:\\work\\SLGEM\\output\\Debug");
PyRun_SimpleString(_T("import sys"));
PyRun_SimpleString(path);
//PyRun_SimpleString("import sys");
//PyRun_SimpleString("sys.path.append('C:/Users/Shen/Desktop/TestPython/TestPython/Debug')");
// 加载模块
PyObject* pModule = PyImport_ImportModule("PythonTest");//此处是python文件名
if (!pModule) // 加载模块失败
{
return ;
}
// 加载函数
PyObject* pv = PyObject_GetAttrString(pModule, "Test_add");//此处是python文件中的函数名称
if (!pv || !PyCallable_Check(pv)) // 验证是否加载成功
{
return ;
}
// 设置参数
PyObject* args = PyTuple_New(2); // 2个参数
//构建两个参数
PyTuple_SetItem(args, 0, Py_BuildValue("i", 8));//0--序号,i表示创建int型变量
PyTuple_SetItem(args, 1, Py_BuildValue("i", 6));//1--序号,i表示创建int型变量
// 调用函数
PyObject* pRet = PyObject_CallObject(pv, args);
//将返回值转换为int类型
int result;
PyArg_Parse(pRet, "i", &result);//i表示转换成int型变量
cout << "6 + 8 = " << result << endl;
Py_Finalize();
3)上面代码注释中有提到,第2)步编译没有问题之后,需要把python文件拷贝到与应用程序(.exe)同目录下,程序才能正常运行。
4)将Python37_d.dll拷贝到与应用程序.exe)同目录下,程序才能正常运行,此文件在python安装目录下。(此处根据你自己编译的版本决定,如release,需要拷贝Python37.dll)。
5)至此,完成c++调用python的配置调用。本人也是在网上学习,查看了好几个介绍,然后进行整理,方便自己以后学习。
6)以上只是实现了c++调用python的多个参数传递,下面实现list(数组)传递方式:
Py_Initialize(); // 初始化
// 加载模块
PyObject* pModule = PyImport_ImportModule("PythonTest");
if (!pModule) // 加载模块失败
{
return ;
}
// 加载函数
PyObject* pv = PyObject_GetAttrString(pModule, "Test_add");
if (!pv || !PyCallable_Check(pv)) // 验证是否加载成功
{
return ;
}
// 设置参数
PyObject* args = PyTuple_New(2); // 2个参数
//两个入参分别为 x,y 数组,大小为3
PyObject* pyListX = PyList_New(3);
PyObject* pyListY = PyList_New(3);
for(int i=0; i<3; i++)
{
PyList_SetItem(pyListX, i, PyFloat_FromDouble(i));
PyList_SetItem(pyListY, i, PyFloat_FromDouble(i+1));
}
//构建两个参数
PyTuple_SetItem(args, 0, pyListX);//0--序号,i表示创建int型变量
PyTuple_SetItem(args, 1, pyListY);//1--序号,i表示创建int型变量
// 调用函数
PyObject* pRet = PyObject_CallObject(pv, args);
//检查是否为List对象
if(PyList_Check(pRet ))
{
int SizeOfList = PyList_Size(pRet );//List对象的大小,这里SizeOfList = 3
for(int i = 0; i < SizeOfList; i++)
{
PyObject *ListItem = PyList_GetItem(pRet, i);//获取List对象中的每一个元素
double result = PyFloat_AsDouble(ListItem);//将python中返回的list元素转换double
PyArg_Parse(ListItem, "f", &result);//f表示转换成int型变量,另外一种转换方法
//下面注释部分表示,如果返回的是一个二维list,需要进一步获取子元素list的大小,然后循环获取子元素list中的元素,进行转换,本例子返回一维list,所以此处注释。
//int NumOfItems = PyList_Size(ListItem);//List对象子元素的大小
//for(int Index_k = 0; Index_k < NumOfItems; Index_k++)
//{
//PyObject *Item = PyList_GetItem(ListItem, Index_k);//遍历List对象中子元素中的每个元素
//double value= PyFloat_AsDouble(Item); //输出元素
//Py_DECREF(Item); //释放空间
//}
Py_DECREF(ListItem); //释放空间
}
}
Py_Finalize();
实例下载:https://download.youkuaiyun.com/download/shenhch/11262434