C++代码中调用Python处理脚本的方式

前言(背景介绍)

因为项目中需要使用到Python脚本,而主代码是用C++书写的,因此需要实现C++调用Python。
因为此篇文章主要起测试连接作用,因此使用比较简单,下方为Python脚本内容:

# 文件名称:usePython.py

def hello():
	print("Hello python")

def add(arg1, arg2):
	return arg1 + arg2

要想使用Python,主要分为两大步:环境配置、代码中调用Python文件。

一:环境配置

在查阅了相关资料之后,特将基础操作总结如下:

1. 安装Python

我是用的是Python3.8.1版本,如下图所示:
在这里插入图片描述
直接双击安装,默认路径为C:\Users\admin\AppData\Local\Programs\Python\Python38,安装结束后Python38路径下内容如下所示:
在这里插入图片描述

2. 创建C++项目

这一步就不多说了。

3. 拷贝文件夹

这一步主要配置的是Python安装路径下的include文件夹和libs文件夹,需要将这两个文件夹拷贝到工程中,因为项目比较简单,因此直接放在了工程文件夹下,如下图所示:
在这里插入图片描述
这一步需要注意的是,原路径下只有python38.lib,这个是针对于release项目的,在debug模式下,需要将之拷贝一份,并将名称改为python38_d.lib,如下两张图所示(第一张:Python安装路径下,第二张:工程项目下)
在这里插入图片描述
在这里插入图片描述

4. 在VS中配置Python内容

配置好include和lib路径,以及在debug和release模式下使用到的.lib名称(就是普通的静态库、动态库配置的方式),如下几张图所示。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

5. 将py文件拷贝到可执行程序目录下

如下图所示:
在这里插入图片描述

二:代码中调用py文件

上面已经做好了相关的配置,现在就可以正式开始使用py文件了。
也主要分为两大块,一个是调用没有参数的py函数,一个是调用有参数的py函数。
话不多说,先上代码:

#include <iostream>
#include <Python.h> //包含Python头文件以使用Python的相关函数

using namespace std;

int main(int argc, char* argv[])
{
	Py_Initialize(); //初始化Python的相关内容(必填项)

	if (Py_IsInitialized()) //判断是否初始化成功
	{
		PyObject *pModule = nullptr;
		PyObject *pFunc = nullptr;

		pModule = PyImport_ImportModule("usePython"); //导入Python脚本模块

		if (pModule)
		{
			///< 调用无参函数
			pFunc = PyObject_GetAttrString(pModule, "hello");
			PyEval_CallObject(pFunc, nullptr);

			///< 调用有参函数
			pFunc = PyObject_GetAttrString(pModule, "add");
			
			PyObject *args = PyTuple_New(2);
			PyObject *arg1 = PyLong_FromLong(3);
			PyObject *arg2 = PyLong_FromLong(8);
			PyTuple_SetItem(args, 0, arg1);
			PyTuple_SetItem(args, 1, arg2);

			PyObject *pResult = PyObject_CallObject(pFunc, args);
			if (pResult)
			{
				long result = PyLong_AsLong(pResult);
				cout << result << endl;
			}
		}
	}

	system("pause");

	return 0;
}

1. 初始化

如上述代码所示,在调用Python函数之前,需要先调用Py_Initialized()函数进行初始化操作,这一步是必须的。
其实在正式项目中,在初始化之前还需要判断Python是否已经安装,这一步就不多说了,毕竟这里仅仅是进行一个简单的调用操作。

这里面的基本单元都是PyObject对象无论是模块、函数、参数、返回值在这里面全部是PyObject对象

2. 导入python脚本模块

接下来就是导入python模块了。

导入模块听起来高端,实际上可以简单理解为将py脚本文件加载进代码中

使用的函数是:pModule = PyImport_ImportModule(“usePython”);
其中userPython就是我自己写的python脚本文件的名称。

3. 函数调用

在判断模块成功导入之后,就可以开始正式的函数调用了。
函数调用主要分为两大类:无参函数,有参函数
以下分别进行介绍。

3.1 无参函数调用

这里面的无参函数就是hello函数了,具体的使用如下:

pFunc = PyObject_GetAttrString(pModule, "hello");
PyEval_CallObject(pFunc, nullptr);

因为没有参数,所以使用起来非常简单,通过函数名得到这个函数,然后直接执行即可

(具体的函数因为不甚了解,因此这里不多说,等我了解之后,将会再开一片博客详细介绍)

3.2 有参函数调用

有参函数的调用相对来说比较麻烦,详见下方代码:

pFunc = PyObject_GetAttrString(pModule, "add");
			
PyObject *args = PyTuple_New(2);
PyObject *arg1 = PyLong_FromLong(3);
PyObject *arg2 = PyLong_FromLong(8);
PyTuple_SetItem(args, 0, arg1);
PyTuple_SetItem(args, 1, arg2);

PyObject *pResult = PyObject_CallObject(pFunc, args);
if (pResult)
{
	long result = PyLong_AsLong(pResult);
	cout << result << endl;
}

这里面就说到了在这种方式下,操作的基本单元是PyObject对象,无论是参数还是返回值。

但是因为PyObject只是一个对象,那么如果想要传入多个参数该如何处理呢?
这就是使用到了tuple,也就是这里面的 PyObject *args = PyTuple_New(2); 这句话,这句话的意思是将args声明为一种元组类型的PyObject对象,这样它就可以存放多个参数了。

返回值也同样如此,返回值也是PyObject类型,根据需要将之转化为自己需要的类型。

另外值得注意的是,需要进行类型的转化,毕竟是数字转化为一个指针类型,需要进行相关的操作。

4. 结果演示

在这里插入图片描述

参考链接

详解C++调用Python脚本中的函数的实例代码
讲述C++中调用Python脚本
使用C++调用Python代码的方法详解
C++ 调用Python脚本

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值