浅析 C++ 调用 Python 模块
来源:互联网 发布:淘宝直通车退款 编辑:程序博客网 时间:2024/05/19 18:45
浅析 C++ 调用 Python 模块
作为一种胶水语言,Python 能够很容易地调用 C 、 C++ 等语言,也能够通过其他语言调用 Python 的模块。
Python 提供了 C++ 库,使得开发者能很方便地从 C++ 程序中调用 Python 模块。
具体的文档参考官方指南:
Embedding Python in Another Application
调用方法
1 链接到 Python 调用库
Python 安装目录下已经包含头文件( include
目录)和库文件 ( Windows 下为 python27.lib
)。
使用之前需要链接到此库。
2 直接调用 Python 语句
#include "python/Python.h"int main(){ Py_Initialize(); ## 初始化 PyRun_SimpleString("print 'hello'"); Py_Finalize(); ## 释放资源}
3 加载 Python 模块并调用函数
~/test
目录下含有 test.py
:
def test_add(a, b): print 'add ', a, ' and ', b return a+b
则可以通过以下代码调用 test_add
函数 :
#include "python/Python.h"#include <iostream>using namespace std;int main(){ Py_Initialize(); // 初始化 // 将Python工作路径切换到待调用模块所在目录,一定要保证路径名的正确性 string path = "~/test"; string chdir_cmd = string("sys.path.append(\"") + path + "\")"; const char* cstr_cmd = chdir_cmd.c_str(); PyRun_SimpleString("import sys"); PyRun_SimpleString(cstr_cmd); // 加载模块 PyObject* moduleName = PyString_FromString("test"); //模块名,不是文件名 PyObject* pModule = PyImport_Import(moduleName); if (!pModule) // 加载模块失败 { cout << "[ERROR] Python get module failed." << endl; return 0; } cout << "[INFO] Python get module succeed." << endl; // 加载函数 PyObject* pv = PyObject_GetAttrString(pModule, "test_add"); if (!pv || !PyCallable_Check(pv)) // 验证是否加载成功 { cout << "[ERROR] Can't find funftion (test_add)" << endl; return 0; } cout << "[INFO] Get function (test_add) succeed." << endl; // 设置参数 PyObject* args = PyTuple_New(2); // 2个参数 PyObject* arg1 = PyInt_FromLong(4); // 参数一设为4 PyObject* arg2 = PyInt_FromLong(3); // 参数二设为3 PyTuple_SetItem(args, 0, arg1); PyTuple_SetItem(args, 1, arg2); // 调用函数 PyObject* pRet = PyObject_CallObject(pv, args); // 获取参数 if (pRet) // 验证是否调用成功 { long result = PyInt_AsLong(pRet); cout << "result:" << result; } Py_Finalize(); ## 释放资源 return 0;}
参数传递
1 C++ 向 Python 传递参数
Python 的参数实际上是元组,因此传参实际上就是构造一个合适的元组。
常用的有两种方法:
使用
PyTuple_New
创建元组,PyTuple_SetItem
设置元组值PyObject* args = PyTuple_New(3);PyObject* arg1 = Py_BuildValue("i", 100); // 整数参数PyObject* arg2 = Py_BuildValue("f", 3.14); // 浮点数参数PyObject* arg3 = Py_BuildValue("s", "hello"); // 字符串参数PyTuple_SetItem(args, 0, arg1);PyTuple_SetItem(args, 1, arg2);PyTuple_SetItem(args, 2, arg3);
直接使用Py_BuildValue构造元组
PyObject* args = Py_BuildValue("(ifs)", 100, 3.14, "hello");PyObject* args = Py_BuildValue("()"); // 无参函数
i
,s
,f
之类的格式字符串可以参考 格式字符串
2 转换 Python 返回值
调用 Python 得到的都是PyObject对象,因此需要使用 Python 提供的库里面的一些函数将返回值转换为 C++ , 例如 PyInt_AsLong
,PyFloat_AsDouble
, PyString_AsString
等。
还可以使用 PyArg_ParseTuple
函数来将返回值作为元组解析。
PyArg_Parse
也是一个使用很方便的转换函数。
PyArg_ParseTuple
和 PyArg_Parse
都使用 格式字符串
注意事项
- 需要将 Python 的工作目录切换到模块所在路径
- 按照模块名加载而不是文件名
- 模块加载或者函数加载需要验证是否成功,否则可能会引起堆栈错误导致程序崩溃
- 需要使用
Py_DECREF(PyObject*)
来解除对象的引用(以便Python垃圾回收)
2 0
- 浅析 C++ 调用 Python 模块
- PYTHON 调用 C/C++模块
- C调用python,如何调用pymongo模块
- python调用C模块的方法
- Python使用bitey调用C模块
- Python与C/C++ 模块相互调用
- Python与C/C++ 模块相互调用
- Python与C/C++ 模块相互调用
- linux 下C调用Python 模块
- Python与C/C++ 模块相互调用
- linux 下Python调用C模块
- linux 下C调用Python 模块
- linux 下Python调用C模块
- linux 下Python调用C模块
- Python调用C模块和性能分析
- linux 下C调用Python 模块
- linux 下C调用Python 模块
- Python 调用C模块以及性能分析
- HDU.1027 Ignatius and the Princess II【全排列:关于next_permutation问题】(3.14)
- [BZOJ 2176]Strange string
- 顺时针旋转矩阵
- vector--resize
- coordinatorLayout 的一个小效果
- 浅析 C++ 调用 Python 模块
- rucheng_hjp_tables
- D11
- GNU ERE正则表达式实现方案
- HDU 2120 Ice_cream's world I
- JAVA学习总结(1)
- hibernate中cascade和inverse区别
- 使用JAVA SACLA 开发 Spark SQL DataFrame IMF内部课程
- Windows系统结构的中断(1)