C++调用Python方法
来源:互联网 发布:c 构造函数编程例子 编辑:程序博客网 时间:2024/06/07 11:00
C++调用Python方法
文章来源:
1.http://blog.csdn.net/feitianxuxue/article/details/41129677
2.http://blog.csdn.net/c_cyoxi/article/details/23978007
3.http://blog.csdn.net/magictong/article/details/8947892
Python/CAPI简介
通过C++调用Python脚本,主要利用Python提供的API,实际上,C++主要调用的是Python的解释器,而Python的解释器本质就是实现在动态链接库里的,因此在调用前后要进行一些初始化和资源释放的工作,另外,要调用Python脚本里的函数等等,需要使用Python提供的一些特殊的API来包装C++调用。
(1) 初始化Python解释器,若初始化失败,继续调用会出现各种错误
void Py_Initialize(void)
(2) 检查Python解释器是否初始化,返回0表示没有经过初始化
int Py_IsInitialized(void)
(3) 反初始化解释器,包括子解释器,同时释放Python解释器占用的资源
void Py_Finalize()
(4) 实际上是一个宏,执行Python代码
int PyRun_SimpleString(const char *command)
(5) 导入一个模块,name是Python文件的文件名,不带.py,类似于Python内建的import
PyObject* PyImport_ImportModule(char *name)
(6) 相当于Python模块对象的dict属性,得到模块名称空间下的字典对象
PyObject* PyModule_GetDict( PyObject *module)
(7) 执行一段Python代码
PyObject* PyRun_String(const char* str, int start,PyObject* globals, PyObject* locals)
(8) 把Python数据类型转换为C的类型
int PyArg_Parse(PyObject* args, char* format, ...)
(9) 返回模块对象o的attr_name属性或函数,相当于Python中的表达式o.attr_name
PyObject* PyObject_GetAttrString(PyObject *o, char*attr_name)
(10) 构建一个参数列表,将C类型转换为Python对象
PyObject* Py_BuildValue(char* format, ...)
(11) 调用Python函数,两个参数都是Python对象指针,pfunc是要调用的Python函数,一般来说,可以用过PyObject_GetAttrString()获得,pargs是函数的参数列表,通常是Py_BuildValue()来构建的
PyObject* PyEval_CallObject(PyObject* pfunc, PyObject*pargs)
错误分析
编译若出现unresolved external symbol _Py_Initialize referenced in function "void __cdecl test(void)" (?test@@YAXXZ)
等错误,可能是工程的platform和Python有着不同bit,将工程转换为32位或者64位与Python一致即可
Python的C模块不支持Debug模式,所以Debug下编译会出现找不到pythonxx_d.lib的错误,需要修改Python头文件pyconfig.h的配置,将Debug库文件换成pythonxx.lib即可
即将
# ifdef _DEBUG # pragma comment(lib,"python27_d.lib") # else # pragma comment(lib,"python27.lib")
修改为:
# ifdef _DEBUG # pragma comment(lib,"python27.lib") # else # pragma comment(lib,"python27.lib")
代码示例:
#include <Python.h>#pragma comment(lib,"python27.lib")using namespace std;void getCurrent(){ PyRun_SimpleString("import sys"); //对于模块和程序不在同一个目录下,执行该Python语句将模块路径加进程序 PyRun_SimpleString("sys.path.append('./Python')"); return;}void test(){ //执行Python语句 Py_Initialize(); PyRun_SimpleString("print 'Hello Python'"); Py_Finalize(); return ;}void test2(){ //调用函数,传入参数,无返回值 Py_Initialize(); getCurrent(); PyObject *pModule = NULL; PyObject *pFunc = NULL; PyObject *pArgs = NULL; pModule = PyImport_ImportModule("pyTest");//引用模块 pFunc = PyObject_GetAttrString(pModule,"print_arg");//取出模块中的函数 pArgs = Py_BuildValue("(s)","Hello_Python");//对要传给函数的参数做类型转换 PyEval_CallObject(pFunc,pArgs);//调用函数并传递参数 Py_Finalize(); return;}void test3(){ //调用函数,传递参数并接受返回值 Py_Initialize(); getCurrent(); int sum = 0; PyObject *pModule = NULL; PyObject *pFunc = NULL; PyObject *pArgs = NULL; PyObject *pResult = NULL; pModule = PyImport_ImportModule("pyTest");//引用模块 pFunc = PyObject_GetAttrString(pModule,"add");//取出模块中的函数 pArgs = Py_BuildValue("(i,i)",3,5);//对要传给函数的参数做类型转换 pResult = PyEval_CallObject(pFunc,pArgs);//调用该函数并接受返回值 PyArg_Parse(pResult,"i",&sum);//将返回值转换为C/C++类型 Py_Finalize(); cout<<sum<<endl;}void test4(){ //调用类,并接受单个返回值 Py_Initialize(); getCurrent(); char *name = NULL; PyObject *pModule = NULL; PyObject *pDict = NULL; PyObject *pClass = NULL; PyObject *pInstance = NULL; PyObject *pResult = NULL; pModule = PyImport_ImportModule("pyTest");//引用模块 pDict = PyModule_GetDict(pModule);//获取模块字典属性 pClass = PyDict_GetItemString(pDict,"pyTest");//通过字典属性获取模块中的类 pInstance = PyInstance_New(pClass,NULL,NULL);//实例化获取的类 //调用类的fun方法,并传入参数Sherlock pResult = PyObject_CallMethod(pInstance,"fun","(s)","Sherlock"); PyArg_Parse(pResult,"s",&name); cout<<name<<endl; Py_Finalize();}void test5(){ //调用类,返回值是json Py_Initialize(); if (!Py_IsInitialized()) { cout<<"Init fail."<<endl; return; } getCurrent(); char *name = NULL; int age = 0; PyObject *pModule = NULL; PyObject *pDict = NULL; PyObject *pClass = NULL; PyObject *pInstance = NULL; PyObject *pResult = NULL; PyObject *obj_content = NULL; PyObject *obj_flag = NULL; pModule = PyImport_ImportModule("pyTest");//引用模块 pDict = PyModule_GetDict(pModule);//获取模块字典属性 pClass = PyDict_GetItemString(pDict,"pyTest");//通过字典属性获取模块中的类 pInstance = PyInstance_New(pClass,NULL,NULL);//实例化获取的类 //调用类方法fun,并传入两个参数,注意参数类型,并获取返回值 pResult = PyObject_CallMethod(pInstance,"fun","(s,i)","Sherlock",100); obj_content = PyDict_GetItemString(pResult,"name");/取出返回值key为name的value name = PyString_AsString(obj_content);//将类型转换为C/C++类型 obj_flag = PyDict_GetItemString(pResult,"age"); age = PyInt_AsLong(obj_flag); cout<<name<<endl; cout<<age<<endl; Py_Finalize();}int _tmain(int argc, _TCHAR* argv[]){ //test();//直接执行Python语句 //test2();//调用函数并传入参数 //test3();//调用函数,传递参数并接受返回值 //test4();//调用类,并接受单个返回值 test5();//调用类,返回值是json return 0;}
- python调用c的方法
- python 调用 C语言 方法
- C/C++中如何调用Python方法
- python调用C模块的方法
- Python调用C/C++的种种方法
- Python调用C/C++的种种方法
- Python调用C/C++的种种方法
- Python调用C/C++的种种方法
- Python调用C/C++的种种方法
- Python调用C/C++的种种方法
- Python调用C/C++的种种方法
- Python调用C/C++的种种方法
- Python调用C/C++的种种方法
- python调用c动态库方法练习
- 转帖:C/C++中如何调用Python方法
- 利用swig实现python调用C/C++的方法
- Python调用C/C++动态链接库的方法详解
- python调用c语言函数的一种简单实现方法
- eclipse编译xml文件完成后还是原来的内容
- TCP和UDP的区别(转)
- swift3.0中@escaping 和 @noescape 的含义
- 查询linux目录下边 特定文件中 特定内容
- codeforces 743 C. Vladik and fractions (数学)
- C++调用Python方法
- 《JAVA与模式》之工厂方法模式
- php-fpm中启用慢日志配置
- 更改ios顶部状态栏字体颜色
- 子元素相对祖先元素居中显示
- unix 编程随笔
- HTML5触摸事件touch监听
- Entitlements 延伸
- mysql 启动一般问题