解决方案。
第 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;
...
}
在我们获得result->obj =
之前插入:resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_Module, SWIG_POINTER_NEW | 0 );
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 );
}
这有效地覆盖了默认生成的用于包装新模块对象的代码。