C/C++调用python

本文介绍如何在C++中调用Python程序,包括无参函数、带参数函数及数组等不同情况,并提供了详细的代码示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

程序配置:
python3.5
VS2012


Python2.x 也可以参考

1、环境配置
参考:http://blog.youkuaiyun.com/chunleixiahe/article/details/50410208这篇文章有详细介绍

2、第一个程序(调用无参函数)

使用到的Python程序:

# hello.py
# coding:utf-8

import numpy as np

def print_arr():
    da=np.zeros((2,2))
    print(da)
    return 1

对应的cpp程序:

#include "Python.h"
#include <iostream>
using namespace std;

int main(int argc, char* argv[])
{
 Py_Initialize();
 if (!Py_IsInitialized())
 {
  return -1;
 }
 PyObject *pModule = NULL;
 pModule = PyImport_ImportModule("hello");  //导入hello.py 
 if (!pModule)
 {
  printf("not found .py file\n");
 }

 PyObject *pFunc = NULL;
 PyObject *pValue = NULL;
 PyObject *pArgs=NULL;

//方法一   
//直接调用hello.py中的print_arr  其中"()"表示无参数 
 printf("方法一\n");
pValue = PyObject_CallMethod(pModule, "print_arr", "()");   
cout << PyLong_AsLong(pValue) << endl; //只能转换一个数值(Py中的long转成C++中的long),如果多于1个数值就会出错

//方法二
 printf("方法二\n");
pFunc = PyObject_GetAttrString(pModule, "print_arr"); //也可以使用该函数得到函数对象
pValue = PyObject_CallFunction(pFunc, "()");
cout << PyLong_AsLong(pValue) << endl;

//方法三
printf("方法三\n");
pFunc = PyObject_GetAttrString(pModule, "print_arr"); 
pArgs=PyTuple_New(0);
pValue = PyObject_CallObject(pFunc, pArgs);
cout << PyLong_AsLong(pValue) << endl;


Py_Finalize(); /* 结束Python解释器,释放资源 */
system("pause");

 return 0;
}

运行结果:
这里写图片描述

结果证明,可行!

3、第二个程序(1个参数)

Python程序:

# hello.py
# coding:utf-8
import numpy as np

def change(data):
    da=np.array(data,dtype=float)
    print(da)
    return 10

cpp程序:

#include "Python.h"
#include <iostream>
using namespace std;

int main(int argc, char* argv[])
{
 Py_Initialize();
 if (!Py_IsInitialized())
 {
  return -1;
 }
 PyObject *pModule = NULL;
 pModule = PyImport_ImportModule("hello");  //导入hello.py 
 if (!pModule)
 {
  printf("not found .py file\n");
 }

 PyObject *pFunc = NULL;
 PyObject *pValue = NULL;
 PyObject *pArgs=NULL;

//方法一   
//直接调用hello.py中的print_arr  
 printf("方法一\n");
pValue = PyObject_CallMethod(pModule, "change", "i",1);   
cout << PyLong_AsLong(pValue) << endl; //只能转换一个数值(Py中的long转成C++中的long),如果多于1个数值就会出错

//方法二
 printf("方法二\n");
pFunc = PyObject_GetAttrString(pModule, "change"); //也可以使用该函数得到函数对象
pValue = PyObject_CallFunction(pFunc, "i",1);
cout << PyLong_AsLong(pValue) << endl;

//方法三
printf("方法三\n");
pFunc = PyObject_GetAttrString(pModule, "change"); 
pArgs=PyTuple_New(1);
PyTuple_SetItem(pArgs, 0, Py_BuildValue("i", 1)); 
pValue = PyObject_CallObject(pFunc, pArgs);
cout << PyLong_AsLong(pValue) << endl;


Py_Finalize(); /* 结束Python解释器,释放资源 */
system("pause");

 return 0;
}

运行结果:
这里写图片描述

事实胜于雄辩!

3.1、传一个数组做参数

cpp程序:

#include "Python.h"
#include <iostream>
using namespace std;

int main(int argc, char* argv[])
{
 Py_Initialize();
 if (!Py_IsInitialized())
 {
  return -1;
 }
 PyObject *pModule = NULL;
 pModule = PyImport_ImportModule("hello");  //导入hello.py 
 if (!pModule)
 {
  printf("not found .py file\n");
 }

 PyObject *pFunc = NULL;
 PyObject *pValue = NULL;
 PyObject *pArgs=NULL;

//方法一   
//直接调用hello.py中的print_arr
 printf("方法一\n");
pValue = PyObject_CallMethod(pModule, "change", "((ii))",1,2);   
cout << PyLong_AsLong(pValue) << endl; //只能转换一个数值(Py中的long转成C++中的long),如果多于1个数值就会出错

//方法二
 printf("方法二\n");
pFunc = PyObject_GetAttrString(pModule, "change"); //也可以使用该函数得到函数对象
pValue = PyObject_CallFunction(pFunc, "[ii]",1,2);
cout << PyLong_AsLong(pValue) << endl;

//方法三
printf("方法三\n");
pFunc = PyObject_GetAttrString(pModule, "change"); 
pArgs=PyTuple_New(1);
PyTuple_SetItem(pArgs, 0, Py_BuildValue("[iiii]", 1,2,3,4)); 
pValue = PyObject_CallObject(pFunc, pArgs);
cout << PyLong_AsLong(pValue) << endl;


Py_Finalize(); /* 结束Python解释器,释放资源 */
system("pause");

 return 0;
}

运行结果:
这里写图片描述

3.2、传一个数组做参数(数组长度很长)
cpp程序:

#include "Python.h"
#include <iostream>
using namespace std;

int main(int argc, char* argv[])
{
 Py_Initialize();
 if (!Py_IsInitialized())
 {
  return -1;
 }
 PyObject *pModule = NULL;
 pModule = PyImport_ImportModule("hello");  //导入hello.py 
 if (!pModule)
 {
  printf("not found .py file\n");
 }

 PyObject *pFunc = NULL;
 PyObject *pValue = NULL;
 PyObject *pArgs=NULL;
 PyObject *pList=NULL;

/*  
//方法一   
//直接调用hello.py中的print_arr  其中"()"表示无参数 
 printf("方法一\n");
pValue = PyObject_CallMethod(pModule, "change", "((ii))",1,2);   
cout << PyLong_AsLong(pValue) << endl; //只能转换一个数值(Py中的long转成C++中的long),如果多于1个数值就会出错
*/
/*
//方法二
 printf("方法二\n");
pFunc = PyObject_GetAttrString(pModule, "change"); //也可以使用该函数得到函数对象
pValue = PyObject_CallFunction(pFunc, "[ii]",1,2);
cout << PyLong_AsLong(pValue) << endl;
*/
//方法三
printf("方法三\n");
pFunc = PyObject_GetAttrString(pModule, "change"); 
pArgs=PyTuple_New(1);
pList=PyList_New(0);//一个空列表

for(int i=0;i<10;i++)
{
    PyList_Append(pList,Py_BuildValue("i",i)); // 使用append将值放入列表中
}
PyTuple_SetItem(pArgs,0,pList);//将列表pList作为参数赋给pArgs

//PyTuple_SetItem(pArgs, 0, Py_BuildValue("[iiii]", 1,2,3,4)); 
pValue = PyObject_CallObject(pFunc, pArgs);
cout << PyLong_AsLong(pValue) << endl;


Py_Finalize(); /* 结束Python解释器,释放资源 */
system("pause");

 return 0;
}

运行结果:
这里写图片描述

4、第3个程序(多个参数)

Python程序:

# hello.py
# coding:utf-8
import numpy as np

def change(data1,data2):
    # da=np.array(data,dtype=float)
    print(data1+data2)
    return (data1+data2)

cpp程序:

#include "Python.h"
#include <iostream>
using namespace std;

int main(int argc, char* argv[])
{
 Py_Initialize();
 if (!Py_IsInitialized())
 {
  return -1;
 }
 PyObject *pModule = NULL;
 pModule = PyImport_ImportModule("hello");  //导入hello.py 
 if (!pModule)
 {
  printf("not found .py file\n");
 }

 PyObject *pFunc = NULL;
 PyObject *pValue = NULL;
 PyObject *pArgs=NULL;
 PyObject *pList=NULL;


//方法一   
//直接调用hello.py中的print_arr  其中"()"表示无参数 
 printf("方法一\n");
pValue = PyObject_CallMethod(pModule, "change", "ii",1,2);   
cout << PyLong_AsLong(pValue) << endl; //只能转换一个数值(Py中的long转成C++中的long),如果多于1个数值就会出错

//方法二
 printf("方法二\n");
pFunc = PyObject_GetAttrString(pModule, "change"); //也可以使用该函数得到函数对象
pValue = PyObject_CallFunction(pFunc, "(ii)",1,2);
cout << PyLong_AsLong(pValue) << endl;

//方法三
printf("方法三\n");
pFunc = PyObject_GetAttrString(pModule, "change"); 
pArgs=PyTuple_New(2);

PyTuple_SetItem(pArgs, 0, Py_BuildValue("i", 1)); 
PyTuple_SetItem(pArgs, 1, Py_BuildValue("i", 2));
pValue = PyObject_CallObject(pFunc, pArgs);
cout << PyLong_AsLong(pValue) << endl;

Py_Finalize(); /* 结束Python解释器,释放资源 */
system("pause");

 return 0;
}

运行结果:
这里写图片描述

5、总结

暂时先写这么多,以后还会不定期更新!

### C/C++ 调用 Python 函数并传递参数 #### 使用 `Pybind11` 实现 C++Python 交互 为了使 C++ 程序能够调用 Python 中定义的功能,可以采用多种方法。其中一种流行的方法是利用 `pybind11` 库来简化这一过程[^2]。 安装好必要的依赖之后,在C++端编写如下代码: ```cpp #include <iostream> #include <pybind11/embed.h> // everything needed for embedding namespace py = pybind11; int main() { py::scoped_interpreter guard{}; // start the interpreter and keep it alive auto plus_function = py::module_::import("example").attr("add"); int a = 9; double b = 3.14; try{ float result = plus_function(a, b).cast<float>(); std::cout << "The sum of " << a << " + " << b << " is: " << result << '\n'; } catch (const py::error_already_set& e){ PyErr_Print(); } } ``` 这段代码展示了如何导入名为 `"example"` 的模块,并从中获取一个叫做 `add` 的函数对象;接着创建两个数值类型的变量作为输入给该函数,最后捕获异常处理可能发生的错误情况。 #### 基于 Python API 扩展方式 另一种更为底层的方式涉及直接操作Python解释器API来进行跨语言通信。这种方式相对更灵活但也更加复杂一些。下面是一个简单的例子说明怎样设置环境以及调用带有参数的Python函数[^1]。 首先初始化Python解释器: ```cpp // 初始化Python解释器 Py_Initialize(); if (PyErr_Occurred()) { PyErr_Print(); } // 添加当前目录至Python路径以便找到本地.py文件 PyRun_SimpleString("import sys\n" "sys.path.append('./')"); ``` 随后加载目标`.py`文件里的特定功能: ```cpp PyObject* pName = PyUnicode_DecodeFSDefault("example"); PyObject* pModule = PyImport_Import(pName); Py_DECREF(pName); if (!pModule) { PyErr_Print(); } else { PyObject *pFunc = PyObject_GetAttrString(pModule,"multiply"); if (pFunc && PyCallable_Check(pFunc)) { PyObject *args = PyTuple_New(2); PyObject *arg1 = PyLong_FromLong(5L); PyObject *arg2 = PyFloat_FromDouble(2.7f); PyTuple_SetItem(args, 0, arg1); PyTuple_SetItem(args, 1, arg2); PyObject *resultObj = PyObject_CallObject(pFunc,args); if(resultObj != NULL){ printf("Result of multiply function call: %ld\n", PyLong_AsLong(resultObj)); Py_DECREF(resultObj); } Py_DECREF(args); Py_XDECREF(pFunc); } Py_DECREF(pModule); } Py_Finalize(); ``` 上述片段实现了从指定名称的空间里提取出乘法运算符对应的实体,并向其提供整数与浮点型数据作为实参完成一次远程调用
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值