繁体   English   中英

从python创建的SWIG包装的C ++对象被过早删除

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM