C++ 调用 Python 初探(一)
2016-09-18 17:19
232 查看
为实现在C++中调用 Numpy接口下面对C++中调用Python进行讨论,
这里作为基础部分暂时不涉及对于Numpy的相应接口的调用,而仅仅是Python内置数据结构。
使用GCC配置 C++ 调用 Python 接口的方法
在CodeBlocks中编译器设置中设定, 外部链接库。
在搜索目录中定义:
编译:D:\Python27\include
链接器:D:\Python27\libs
链接器设置:
链接库:D:\Python27\libs\python27.lib
下面展开在C++ 中调用Python的相关讨论:
这里使用了支持C++ 11的GCC编辑器,找到Python相应的指针接口后,重写
相应的Python逻辑为C++,直接调用Python接口即可。(这可以大大加快程序的运行速率)。
一些用到的Python C++指针接口的说明:
void Py_Initialize
初始化python解释器,在调用其他API前应该完成相应的调用。
int PyRun_SimpleString(const char *command)
剩下的比较简单。
使用C++调用Python接口,一般会在调用函数及给出相应函数参数时用到char *format指针,
这个指针一般是用string对象进行初始化的,注意类型与提供的参数要一一对应,在编译
时会抛出warning, 并不能将char* 指向 string,这个现象可以忽视。
python的标准C接口是相对简单的,但Numpy的相应C接口相对复杂,故采用C++代码来重写算法
的方式来编程。
利用Py_INCREF及Py_DECREF可以对PyObject的指针进行引用增减操作,对已释放的内存进行
访问会出错,但这也是及时释放内存的方法。
在使用Python C API时的一个重要问题是内存的释放,如当为了得到python list的某一项时
有两个API接口,一种是PyList_GetItem 另一种是PySequence_GetItem,当使用前者是得到的
是对象(下标对应项)的引用,而后者是一个新的引用,即后者递增了引用计数,
故在使用后一个版本时要注意调用Py_DECREF进行引用计数递减,释放内存。
下面是一个简单的与上述内容相对应的C++代码:
上面提到的有关论述基本上是Python文档中与C进行交互的相关部分,这对于在C++中调用Python已经
足够,文档中剩余的基础部分基本上是对于各种API的列举介绍。(这里忽略了与异常相关的部分)
这里作为基础部分暂时不涉及对于Numpy的相应接口的调用,而仅仅是Python内置数据结构。
使用GCC配置 C++ 调用 Python 接口的方法
在CodeBlocks中编译器设置中设定, 外部链接库。
在搜索目录中定义:
编译:D:\Python27\include
链接器:D:\Python27\libs
链接器设置:
链接库:D:\Python27\libs\python27.lib
下面展开在C++ 中调用Python的相关讨论:
这里使用了支持C++ 11的GCC编辑器,找到Python相应的指针接口后,重写
相应的Python逻辑为C++,直接调用Python接口即可。(这可以大大加快程序的运行速率)。
一些用到的Python C++指针接口的说明:
void Py_Initialize
初始化python解释器,在调用其他API前应该完成相应的调用。
int PyRun_SimpleString(const char *command)
剩下的比较简单。
使用C++调用Python接口,一般会在调用函数及给出相应函数参数时用到char *format指针,
这个指针一般是用string对象进行初始化的,注意类型与提供的参数要一一对应,在编译
时会抛出warning, 并不能将char* 指向 string,这个现象可以忽视。
python的标准C接口是相对简单的,但Numpy的相应C接口相对复杂,故采用C++代码来重写算法
的方式来编程。
利用Py_INCREF及Py_DECREF可以对PyObject的指针进行引用增减操作,对已释放的内存进行
访问会出错,但这也是及时释放内存的方法。
在使用Python C API时的一个重要问题是内存的释放,如当为了得到python list的某一项时
有两个API接口,一种是PyList_GetItem 另一种是PySequence_GetItem,当使用前者是得到的
是对象(下标对应项)的引用,而后者是一个新的引用,即后者递增了引用计数,
故在使用后一个版本时要注意调用Py_DECREF进行引用计数递减,释放内存。
下面是一个简单的与上述内容相对应的C++代码:
#include<iostream> using std::cout; using std::endl; #include<string> using std::string; #include<Python.h> int set_all(PyObject *target, PyObject* item) { int i, n; n = PyObject_Length(target); if (n < 0) return -1; for (i = 0;i < n; i++) { PyObject* index = PyInt_FromLong(i); if (!index) return -1; if (PyObject_SetItem(target, index, item) < 0) { Py_DECREF(index); return -1; } Py_DECREF(index); } return 0; } long sum_list(PyObject* list) { int i, n; long total = 0; PyObject * item; n = PyList_Size(list); if(n < 0) return -1; for(i = 0;i < n;i++) { item = PyList_GetItem(list, i); if (!PyInt_Check(item))continue; total += PyInt_AsLong(item); } return total; } long sum_sequence(PyObject* sequence) { int i, n; long total = 0; PyObject *item; n = PySequence_Length(sequence); if(n < 0) return -1; for(i = 0;i < n;i ++) { item = PySequence_GetItem(sequence, i); if(item == NULL) return -1; if(PyInt_Check(item)) total += PyInt_AsLong(item); Py_DECREF(item); } return total; } int main() { PyObject *pModule, *pValue, *pModule0, *pValue0, *pList; Py_Initialize(); pModule = PyImport_ImportModule("math"); pValue=PyObject_CallMethod(pModule, "sqrt", "f", 100.0); cout << PyFloat_AsDouble(pValue) << endl; PyRun_SimpleString("print 'The work is done.'"); pList = PyList_New(2); cout << PyList_GET_SIZE(pList) << endl; cout << "The type of ptr is or not list :" << PyList_Check(pList)<<endl; //Py_DECREF(pList); cout << "Another condition :"<< PyList_Check(pValue)<< endl; Py_INCREF(pList); Py_DECREF(pList); PyObject *t; t = PyTuple_New(3); PyTuple_SetItem(t, 0, PyInt_FromLong(1L)); PyTuple_SetItem(t, 1, PyInt_FromLong(2L)); PyTuple_SetItem(t, 2, PyString_FromString("three")); PyObject *tuple, *list; tuple = Py_BuildValue("(iis)", 1, 2, "three"); list = Py_BuildValue("[iis]", 1, 2, "three"); PyObject * pTuple; pTuple = Py_BuildValue("(iii)", 10,10, 10); PyObject* n = PyInt_FromLong(1000); int return_val; return_val = set_all(pTuple, n); cout << "The return val is :" << return_val <<endl; int num; num = PyObject_Length(pTuple); for(int i = 0;i < num; i++); cout << PyInt_AsLong(PyTuple_GetItem(pTuple, i)) << " "; cout << endl; PyObject * ppList; ppList = PyList_New(3); ppList = Py_BuildValue("[iii]", 1, 2, 3); num = PyObject_Length(ppList); cout << "Before pList is :\n"; for(int i = 0;i < num; i++) cout << PyInt_AsLong(PyList_GetItem(ppList, i))<< " "; cout << endl; return_val = set_all(ppList, n); cout << "The return val :" <<return_val<< endl; cout << "Now the List is :"; for(int i = 0;i < num; i ++) cout << PyInt_AsLong(PyList_GetItem(ppList, i)) << " "; cout << endl; cout << sum_list(ppList)<<endl; cout << sum_sequence(ppList) << endl; Py_Finalize(); return 0; }
上面提到的有关论述基本上是Python文档中与C进行交互的相关部分,这对于在C++中调用Python已经
足够,文档中剩余的基础部分基本上是对于各种API的列举介绍。(这里忽略了与异常相关的部分)
相关文章推荐
- C++多线程中调用python api函数
- BCB(C++)调用Python
- C++调用PythonAPI线程状态和全局解释器锁
- python嵌入C++------ boost.python如何在C++中调用含有不定长参数tuple变量和关键字参数dict变量的函数
- Python笔记(二)――python调用C/C++模块
- 如何在C++调用Python
- 初始化函数中的虚函数调用( C++ vs python )
- CERL: PHP或Python调用C++实现的服务器
- 如何让python调用C和C++代码
- 如何让python调用C和C++代码
- Python调用采用Boost Python封装的c++(2)
- C++调用Python(4)
- C++多线程中调用python api函数
- CERL: PHP或Python调用C++实现的服务器
- python调用C和C++代码(BOOST)
- C++ 应用程序中 嵌入的python脚本与C++程序的互相调用(访问 通信)
- C++多线程中调用python api函数
- 用C++调用PYTHON脚本
- Python笔记(一)——C/C++调用python
- c++调用python完整代码(开发环境vs2008)