C++中调用python函数注意事项


很多时候我们需要在C++中调用python, 例如调用tensorflow 的一些优化函数,深度学习的模型等等,基本的使用方法如下(当然,要先配置好调用python 的环境。)

#include "stdafx.h"
#include<iostream>
#include <string.h>
#include <string>
#include "python.h"
using namespace std;

int main()
{

	初始化Python环境
	Py_Initialize();

	PyRun_SimpleString("import sys");
	//加入python文件路径
	PyRun_SimpleString("sys.path.append('C:/Users/admin/Desktop/Test')");

	//导入模块(Insert.py)
	PyObject* pModule = PyImport_ImportModule("Insert");

	if (!pModule)
	{
		cout << "Python get module failed." << endl;
		return 0;
	}

	cout << "Python get module succeed." << endl;

	//获取Insert模块内_add函数
	PyObject* pv = PyObject_GetAttrString(pModule, "_add");
	if (!pv || !PyCallable_Check(pv))
	{
		cout << "Can't find funftion (_add)" << endl;
		return 0;
	}
	cout << "Get function (_add) succeed." << endl;

	//初始化要传入的参数,args配置成传入两个参数的模式
	PyObject* args = PyTuple_New(2);
	//将Long型数据转换成Python可接收的类型
	PyObject* arg1 = PyLong_FromLong(4);
	PyObject* arg2 = PyLong_FromLong(3);

	//将arg1配置为arg带入的第一个参数
	PyTuple_SetItem(args, 0, arg1);
	//将arg1配置为arg带入的第二个参数
	PyTuple_SetItem(args, 1, arg2);

	//传入参数调用函数,并获取返回值
	PyObject* pRet = PyObject_CallObject(pv, args);

	if (pRet)
	{
		//将返回值转换成long型
		long result = PyLong_AsLong(pRet);
		cout << "result:" << result;
	}

	Py_Finalize();
	return 0;
}

其中 Insert.py 内容如下:

def _add(x, y):
    print('add', x, 'and', y)
    return x + y

1. C++ 中调用的*.py文件的路径

PyRun_SimpleString("import sys");
PyRun_SimpleString("sys.path.append('你的python文件所在路径')");

注意“你的python文件所在路径”中只能用 ‘/ ’而不能用“ \\”,否则找不到文件。正确的例子如下

PyRun_SimpleString("sys.path.append('D:/workspace')");

2. python 文件中的相对路径问题

如果C++调用的 *.py 中包含了其所在文件夹下的其他需要load 的文件,此时的相对路径不能是 *.py所在的文件,而应该是C++ 工程所在的目录,所以推荐使用绝对路径。例如:

#当被调用的*.py文件在D:/workspace 文件夹下,而C++工程不在该目录下时,需要读取test.txt最好使用以下代码。
data=np.loadtxt("D:/workspace/test.txt") 
#而不用用
data=np.loadtxt("./test.txt") 

3. 返回值是List时,如何读取

假设返回值是float data[43][3], 读取结果的代码如下:

//传入参数调用函数,并获取返回值
	PyObject* pRet = PyObject_CallObject(pv, nullptr);
	float data[34][3] = { 0 };
	if (PyList_Check(pRet)) { //检查是否为List对象

		int SizeOfList = PyList_Size(pRet);//List对象的大小,这里SizeOfList = 3
		for (int Index_i = 0; Index_i < SizeOfList; Index_i++) {

			PyObject * ListItem = PyList_GetItem(pRet, Index_i);//遍历List对象中子元素中的每个元素			
			int NumOfItems = PyList_Size(ListItem);
			for (int Index_k = 0; Index_k < NumOfItems; Index_k++) {

				PyObject *Item = PyList_GetItem(ListItem, Index_k);
				cout << PyFloat_AsDouble(Item) << " ";
				data[Index_i][Index_k] = PyFloat_AsDouble(Item);
				Py_DECREF(Item);
			}
			Py_DECREF(ListItem); //释放空间
		}
		cout << endl;
	}
	else 
	{
		cout << "Not a List" << endl;
	}

其他更多类型的返回值见参考[1]

4. 参考

[1]https://blog.csdn.net/stu_csdn/article/details/69488385

  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
在C语言调用Python函数,需要使用Python的C语言API。以下是一个简单的示例: 1. 在C代码包含Python头文件: ```c #include <Python.h> ``` 2. 初始化Python解释器: ```c Py_Initialize(); ``` 3. 加载Python模块: ```c PyObject *pModule = PyImport_ImportModule("module_name"); ``` 4. 获取Python函数: ```c PyObject *pFunc = PyObject_GetAttrString(pModule, "function_name"); ``` 5. 定义函数参数: ```c PyObject *pArgs = PyTuple_New(number_of_arguments); PyTuple_SetItem(pArgs, 0, PyLong_FromLong(arg1)); PyTuple_SetItem(pArgs, 1, PyLong_FromLong(arg2)); // 添加更多参数 ``` 6. 调用Python函数: ```c PyObject *pResult = PyObject_CallObject(pFunc, pArgs); ``` 7. 处理函数返回值: ```c long result = PyLong_AsLong(pResult); ``` 8. 释放内存: ```c Py_DECREF(pModule); Py_DECREF(pFunc); Py_DECREF(pArgs); Py_DECREF(pResult); ``` 完整的代码示例: ```c #include <Python.h> int main(int argc, char *argv[]) { Py_Initialize(); // 加载Python模块 PyObject *pModule = PyImport_ImportModule("example_module"); // 获取Python函数 PyObject *pFunc = PyObject_GetAttrString(pModule, "example_function"); // 定义函数参数 PyObject *pArgs = PyTuple_New(2); PyTuple_SetItem(pArgs, 0, PyLong_FromLong(10)); PyTuple_SetItem(pArgs, 1, PyLong_FromLong(20)); // 调用Python函数 PyObject *pResult = PyObject_CallObject(pFunc, pArgs); // 处理函数返回值 long result = PyLong_AsLong(pResult); printf("Result: %ld\n", result); // 释放内存 Py_DECREF(pModule); Py_DECREF(pFunc); Py_DECREF(pArgs); Py_DECREF(pResult); Py_Finalize(); return 0; } ```
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值