![](/img/trans.png)
[英]Redirection of stdout from a SWIG-wrapped C++ class to a non-file python object
[英]SWIG wrapped C++ object created from python prematurely deleted
我用SWIG在python中包装了一个C ++类和一个C ++函数。
class Module { ... };
void register_module(Module *m);
函数register_module()将给定的模块放在全局列表中,以便从那时起,C ++代码将指针保留在模块上并使用它。
现在,从嵌入式python解释器运行的以下python代码崩溃 :
>>> register_module(Module())
另一方面,以下python代码不会崩溃 :
>>> m = Module()
>>> register_module(m)
显然,原因是在第一种情况下对象是由python进行垃圾回收的,而在第二种情况下则不是。
防止python删除第一种情况下创建并由C ++代码使用的匿名对象的最佳方法是什么?
在register_module()函数中,是否有办法保持关联的python代理对象,然后增加其引用计数?
(我知道如果有问题的类可以交叉移植到Swig :: Director类,这是可行的,但这假设我们有一个在python中定义的Module子类的实例,在这里不是这种情况) 。
解。
步骤1 :将一个成员添加到Module类,以及两个方法。
class Module {
public:
PyObject *obj;
void incref() { Py_INCREF(obj); }
void decref() { Py_DECREF(obj); }
...
};
步骤2 :增加register_module()中的引用计数。
void register_module(Module *m) {
m->incref();
...
}
(不要忘记在某处减少它)
第3步 :每当使用Python构建Module对象时,请破解由SWIG生成的包装器以将obj成员设置为PyObject包装器。
在SWIG生成的文件ModulePYTHON_wrap.cxx中,找到:
SWIGINTERN PyObject *_wrap_new_Module(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
PyObject *resultobj = 0;
...
Module *result = 0 ;
...
if ( arg1 != Py_None ) {
/* subclassed */
result = (Module *)new SwigDirector_Module(arg1);
} else {
result = (Module *)new Module();
}
resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_Module, SWIG_POINTER_NEW | 0 );
return resultobj;
...
}
在resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_Module, SWIG_POINTER_NEW | 0 );
之前插入resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_Module, SWIG_POINTER_NEW | 0 );
result->obj =
我们获得:
result->obj = resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_Module, SWIG_POINTER_NEW | 0 );
步骤4 :指示SWIG在生成的包装器中自动实施此修复程序。
在接口文件中添加以下类型映射声明。
%typemap(out) Module* {
result->obj = $result = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_Module, SWIG_POINTER_NEW | 0 );
}
这有效地覆盖了默认情况下为包装新的Module对象而生成的代码。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.