cpp extend python 的一种解决方案
2012-01-05 00:16
281 查看
因为python的module机制,python很容易通过c扩充。
官方的方法module,newType:http://docs.python.org/extending/index.html
ctype:http://docs.python.org/library/ctypes.html
但是cpp扩展python还是比较复杂,原因就是cpp的语法比较复杂。
比较好的现有解决方案就是:
boost.python:http://www.boost.org/doc/libs/1_48_0/libs/python/doc/
但是很多时候boost显得太笨重。对于我现在的需求并不合适。
我的基本思想:cpp其实算是用户定义的一个类型,自己提供constructor&destructor,
其实可以将cpp的一个class对应python的一个type。
例如:
在cpp中如下:
class CObject
{
…
};
定义python的new type如下:
typedef struct {
PyObject_HEAD
CObject *pCObject;
} udt_CObject;
static PyObject* PyCObject_New(…)
{…}
static int PyCObject_Init(…)
{…}
static void PyCObject_free(udt_CObject* self)
{…}
static PyMethodDef CObject_Methods[] = {…}
static PyTypeObject CObject_Type = {…}
…
new type对象的构建有两种方式:
1、在cpp环境中创建(cpp嵌入python虚拟机的时候很有效):
udt_CObject*_CObject;
_CObject= (udt_CObject*)CObject_Type.tp_alloc(&CObject_Type, 0);
2、在python环境中创建,import你的动态库test,
object = test.CObject(…)
object.method…
用到的知识:
extending python with c or cpp:http://docs.python.org/extending/extending.html
defining new type:http://docs.python.org/extending/newtypes.html
理解C/CPP基本的编译链接。
注意的问题:
python GIL:多线程的环境下,如果c/cpp API里面有“阻塞”的系统调用,应该释放GIL。但是需要注意的问题是。
python环境传入c API环境的参数(这些对象),其实还是由python管理(其实想想这是合理滴)。Py_BEGIN_ALLOW_THREADS释放GIL
python虚拟机有可能回收这些memory,如果c API调用“引用”了这些地址就可能导致段错误。解决方案就是做适当的memcpy,用变量把传入的参数
的“内容全部收下来“。
异常处理:基本要求就是python至少要知道cpp API调用进入到了exception 控制流。所以cpp API要捕获所有的cpp环境的异常。可以通过返回值或者
riase exception,转换python定义的exception。
返回值:建议用dict,这样容易扩充。
参数接受:最好不用size_t,这个数据类型导致很多兼容性问题。
总结C API要干的事情就是:接受python环境传入的参数,等待是释放GIL,处理返回值。
如果需要更加复杂点的解决方案但是又不能用boost.python
这是个不错的解决方案:http://www.python.org/doc/PyCPP.html
官方的方法module,newType:http://docs.python.org/extending/index.html
ctype:http://docs.python.org/library/ctypes.html
但是cpp扩展python还是比较复杂,原因就是cpp的语法比较复杂。
比较好的现有解决方案就是:
boost.python:http://www.boost.org/doc/libs/1_48_0/libs/python/doc/
但是很多时候boost显得太笨重。对于我现在的需求并不合适。
我的基本思想:cpp其实算是用户定义的一个类型,自己提供constructor&destructor,
其实可以将cpp的一个class对应python的一个type。
例如:
在cpp中如下:
class CObject
{
…
};
定义python的new type如下:
typedef struct {
PyObject_HEAD
CObject *pCObject;
} udt_CObject;
static PyObject* PyCObject_New(…)
{…}
static int PyCObject_Init(…)
{…}
static void PyCObject_free(udt_CObject* self)
{…}
static PyMethodDef CObject_Methods[] = {…}
static PyTypeObject CObject_Type = {…}
…
new type对象的构建有两种方式:
1、在cpp环境中创建(cpp嵌入python虚拟机的时候很有效):
udt_CObject*_CObject;
_CObject= (udt_CObject*)CObject_Type.tp_alloc(&CObject_Type, 0);
2、在python环境中创建,import你的动态库test,
object = test.CObject(…)
object.method…
用到的知识:
extending python with c or cpp:http://docs.python.org/extending/extending.html
defining new type:http://docs.python.org/extending/newtypes.html
理解C/CPP基本的编译链接。
注意的问题:
python GIL:多线程的环境下,如果c/cpp API里面有“阻塞”的系统调用,应该释放GIL。但是需要注意的问题是。
python环境传入c API环境的参数(这些对象),其实还是由python管理(其实想想这是合理滴)。Py_BEGIN_ALLOW_THREADS释放GIL
python虚拟机有可能回收这些memory,如果c API调用“引用”了这些地址就可能导致段错误。解决方案就是做适当的memcpy,用变量把传入的参数
的“内容全部收下来“。
异常处理:基本要求就是python至少要知道cpp API调用进入到了exception 控制流。所以cpp API要捕获所有的cpp环境的异常。可以通过返回值或者
riase exception,转换python定义的exception。
返回值:建议用dict,这样容易扩充。
参数接受:最好不用size_t,这个数据类型导致很多兼容性问题。
总结C API要干的事情就是:接受python环境传入的参数,等待是释放GIL,处理返回值。
如果需要更加复杂点的解决方案但是又不能用boost.python
这是个不错的解决方案:http://www.python.org/doc/PyCPP.html
相关文章推荐
- cpp extend python 的一种解决方案
- 决定将所有小事,偶发的小问题,spark,及其解决方案,全作为一种记录,发到博客上。
- Python3 爬虫笔记, 顺带mysql编码解决方案
- 解决方案:python version 2.7 required,which was not found in
- 关于嵌入式ARM开发板联网的一种解决方案
- 运行django-admin.py运行报 ImportError: No module named django.core的一种解决方案
- get参数过长的一种解决方案
- Swig之cpp完整python扩展疑难对策
- python3+django使用celery执行某些任务失败的解决方案
- Python web多sitemap创建更新解决方案
- Python3 Anaconda3下import cv2错误解决方案
- 环信即时通讯云技术博客——实时网络音视频通讯qos的一种解决方案
- 介绍一种GUI测试的解决方案
- Python 的 type 和 object 之间是怎么一种关系?
- Python用pip 安装lxml时出现 “Unable to find vcvarsall.bat ”解决方案
- windows+python2.7在IDLE中执行sys.exit()出现的问题及解决方案
- Ubuntu12.10下Python(cx_Oracle)访问Oracle解决方案
- 重装python idle打不开解决方案
- python--selenium一种实用的自动生成测试HTML报告方法--HTMLTestRunner
- ssl证书双向认证失效的一种解决方案