C++调用Python
2009-02-27 11:08
435 查看
前两篇都是介绍Python调用C++的,换句话说,就是需要把C++封装成Python可以“理解”的类型。这篇,我打算说一下,C++怎么去调用Python脚本。其实这两者之间是相通的,就是需要可以互操作。按照惯例,先贴代码。
second.cpp
#include <Python.h>
#include <iostream>
#include <string>
void printDict(PyObject* obj)
{
if( !PyDict_Check(obj))
return;
PyObject *k,*keys;
keys = PyDict_Keys(obj);
for(int i = 0; i < PyList_GET_SIZE(keys); i++)
{
k = PyList_GET_ITEM(keys, i);
char* c_name = PyString_AsString(k);
printf("%s/n",c_name);
}
}
int main()
{
Py_Initialize();
if(!Py_IsInitialized())
return -1;
PyRun_SimpleString("import sys");
PyRun_SimpleString("sys.path.append('./')");
//导入模块
PyObject* pModule=PyImport_ImportModule("second");
if(!pModule)
{
printf("Cant open python file!/n");
return -1;
}
//模块的字典列表
PyObject* pDict = PyModule_GetDict(pModule);
if(!pDict)
{
printf("Cant find dictionary./n");
return -1;
}
//打印出来看一下
printDict(pDict);
//获取Second类
PyObject* pClassSecond = PyDict_GetItemString(pDict,"Second");
if( !pClassSecond )
{
printf("Cant find second class./n");
return -1;
}
//构造Second的实例
PyObject* pInstanceSecond = PyInstance_New(pClassSecond,NULL,NULL);
if( !pInstanceSecond)
{
printf("Cant create second instance./n");
return -1;
}
//获取Person类
PyObject* pClassPerson = PyDict_GetItemString(pDict,"Person");
if( !pClassPerson )
{
printf("Cant find person class./n");
return -1;
}
//构造Person的实例
PyObject* pInstancePerson = PyInstance_New(pClassPerson,NULL,NULL);
if( !pInstancePerson )
{
printf("Cant find person instance./n");
return -1;
}
PyObject_CallMethod(pInstanceSecond,"invoke","O",pInstancePerson);
Py_DECREF(pModule); //都需要释放,例子就不写了
Py_Finalize();
getchar();
return 0;
}
second.py
#!/usr/bin/python
# Filename: second.py
class Person:
def sayHi(self):
print 'hi'
class Second:
def sayHello(self):
print 'hello'
def invoke(self,obj):
obj.sayHi()
我简单解释一下
这个例子演示了,创建python中Person类的实例,并作为参数调用Second的方法。
Py_Initialize()和Py_Finalize()是初始和销毁Python解释器
PyRun_SimpleString("import sys")导入sys,接着设置py文件的路径PyRun_SimpleString("sys.path.append('./')")
导入模块PyImport_ImportModule("second"),就是second.py模块。
获取模块字典列表,PyModule_GetDict(pModule),可以打印出来看一下如void printDict(PyObject* obj)函数
从字典中获取类的类型PyDict_GetItemString(pDict,"Second"),如函数也是这样获取的
创造类的实例PyInstance_New(pClassSecond,NULL,NULL)
调用实例的方法PyObject_CallMethod(pInstanceSecond,"invoke","O",pInstancePerson)
整个流程就是这样的,并不复杂,如果要进一步研究可以参考:http://www.python.org/doc/
Extending and Embedding
Python/C API
比较特殊的是调用Python函数时,参数的传递,就是c++的类型,怎么转换成Python的类型;另外一个问题是,Python函数的返回值,怎么转换成C++中的类型。
C++转换成Python类型,Py_BuildValue()
http://www.python.org/doc/1.5.2p2/ext/buildValue.html
PyObject* pArgs=PyTuple_New(1); //有几个参数,就是几
PyTuple_SetItem(pArgs,0,Py_BuildValue("i",3)); //初始第一个参数,数据类型是i,就是int,值是3
返回值转换如,PyArg_ParseTuple,请参考
http://www.python.org/doc/1.5.2p2/ext/parseTuple.html
second.cpp
#include <Python.h>
#include <iostream>
#include <string>
void printDict(PyObject* obj)
{
if( !PyDict_Check(obj))
return;
PyObject *k,*keys;
keys = PyDict_Keys(obj);
for(int i = 0; i < PyList_GET_SIZE(keys); i++)
{
k = PyList_GET_ITEM(keys, i);
char* c_name = PyString_AsString(k);
printf("%s/n",c_name);
}
}
int main()
{
Py_Initialize();
if(!Py_IsInitialized())
return -1;
PyRun_SimpleString("import sys");
PyRun_SimpleString("sys.path.append('./')");
//导入模块
PyObject* pModule=PyImport_ImportModule("second");
if(!pModule)
{
printf("Cant open python file!/n");
return -1;
}
//模块的字典列表
PyObject* pDict = PyModule_GetDict(pModule);
if(!pDict)
{
printf("Cant find dictionary./n");
return -1;
}
//打印出来看一下
printDict(pDict);
//获取Second类
PyObject* pClassSecond = PyDict_GetItemString(pDict,"Second");
if( !pClassSecond )
{
printf("Cant find second class./n");
return -1;
}
//构造Second的实例
PyObject* pInstanceSecond = PyInstance_New(pClassSecond,NULL,NULL);
if( !pInstanceSecond)
{
printf("Cant create second instance./n");
return -1;
}
//获取Person类
PyObject* pClassPerson = PyDict_GetItemString(pDict,"Person");
if( !pClassPerson )
{
printf("Cant find person class./n");
return -1;
}
//构造Person的实例
PyObject* pInstancePerson = PyInstance_New(pClassPerson,NULL,NULL);
if( !pInstancePerson )
{
printf("Cant find person instance./n");
return -1;
}
PyObject_CallMethod(pInstanceSecond,"invoke","O",pInstancePerson);
Py_DECREF(pModule); //都需要释放,例子就不写了
Py_Finalize();
getchar();
return 0;
}
second.py
#!/usr/bin/python
# Filename: second.py
class Person:
def sayHi(self):
print 'hi'
class Second:
def sayHello(self):
print 'hello'
def invoke(self,obj):
obj.sayHi()
我简单解释一下
这个例子演示了,创建python中Person类的实例,并作为参数调用Second的方法。
Py_Initialize()和Py_Finalize()是初始和销毁Python解释器
PyRun_SimpleString("import sys")导入sys,接着设置py文件的路径PyRun_SimpleString("sys.path.append('./')")
导入模块PyImport_ImportModule("second"),就是second.py模块。
获取模块字典列表,PyModule_GetDict(pModule),可以打印出来看一下如void printDict(PyObject* obj)函数
从字典中获取类的类型PyDict_GetItemString(pDict,"Second"),如函数也是这样获取的
创造类的实例PyInstance_New(pClassSecond,NULL,NULL)
调用实例的方法PyObject_CallMethod(pInstanceSecond,"invoke","O",pInstancePerson)
整个流程就是这样的,并不复杂,如果要进一步研究可以参考:http://www.python.org/doc/
Extending and Embedding
Python/C API
比较特殊的是调用Python函数时,参数的传递,就是c++的类型,怎么转换成Python的类型;另外一个问题是,Python函数的返回值,怎么转换成C++中的类型。
C++转换成Python类型,Py_BuildValue()
http://www.python.org/doc/1.5.2p2/ext/buildValue.html
PyObject* pArgs=PyTuple_New(1); //有几个参数,就是几
PyTuple_SetItem(pArgs,0,Py_BuildValue("i",3)); //初始第一个参数,数据类型是i,就是int,值是3
返回值转换如,PyArg_ParseTuple,请参考
http://www.python.org/doc/1.5.2p2/ext/parseTuple.html
相关文章推荐
- C++调用python配置及编译出现的问题
- C++ 调用python脚本,无需解释器
- C++调用python脚本
- python调用C++
- 使用C++调用Python脚本的步骤和问题解决办法
- python中调用C++写的动态库
- python中调用C++写的动态库
- C++中调用python函数
- python嵌入C++------ boost.python如何在C++中调用含有不定长参数tuple变量和关键字参数dict变量的函数
- python 调用C++模块 visual studio版
- c/c++调用python(2)
- linux下使用swig让python调用C++(复杂版:包括多文件调用和链接库)
- c++调用python返回值
- C++多线程调用Python多进程
- 使用GDB调试python调用的C++共享库
- c++调用python(复杂版)
- C++调用Python脚本遇到的问题记录《后续还会添加 方便查阅》
- C++调用Python的工具类
- C++调用Python方法
- 手写选择题识别-c++线上调用 线下python跑出的tensorflow模型-占坑