这是我遇到的问题的一个非常简单的例子。struct Foo 包含包含一个 int 的 struct Bar。如果 Foo 被垃圾回收,那么它的内部 Bar 也会被删除,即使仍然有对该 bar 的引用。
Python代码
import example
def get_bar():
foo = example.Foo()
foo.bar.x = 10
bar = foo.bar
print("before {}".format(bar.x))
return foo.bar # foo (and bar) are deleted when this returns
bar = get_bar()
print("after {}".format(bar.x))
输出
> before 10
> after 39656152
我已经从 C++ 代码中删除了所有指针和引用,希望 SWIG 使用相同的值语义,但它仍在内部将事物转换为 Foo* 和 Bar*。我想我的问题是,如何说服 SWIG 在 _wrap_Foo_bar_get 中制作 bar 的副本?
下面的示例代码:
例子.h
struct Bar {
int x;
};
struct Foo {
Bar bar;
};
例子.i
%module "example"
%{
#include "example.h"
%}
%include "example.h"
CMakeLists.txt
FIND_PACKAGE(SWIG REQUIRED)
INCLUDE(${SWIG_USE_FILE})
FIND_PACKAGE(PythonLibs)
INCLUDE_DIRECTORIES(${PYTHON_INCLUDE_PATH} .)
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR})
SET(CMAKE_SWIG_FLAGS "")
SET_SOURCE_FILES_PROPERTIES(example.i PROPERTIES CPLUSPLUS ON)
SET_SOURCE_FILES_PROPERTIES(example.i PROPERTIES SWIG_FLAGS "-includeall")
SWIG_ADD_MODULE(example python example.i example.h)
SWIG_LINK_LIBRARIES(example ${PYTHON_LIBRARIES})
这是生成的 SWIG 方法,它获取对 bar 的引用,而不是它的值:
SWIGINTERN PyObject *_wrap_Foo_bar_get(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
PyObject *resultobj = 0;
Foo *arg1 = (Foo *) 0 ;
void *argp1 = 0 ;
int res1 = 0 ;
PyObject * obj0 = 0 ;
Bar *result = 0 ;
if (!PyArg_ParseTuple(args,(char *)"O:Foo_bar_get",&obj0)) SWIG_fail;
res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_Foo, 0 | 0 );
if (!SWIG_IsOK(res1)) {
SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Foo_bar_get" "', argument " "1"" of type '" "Foo *""'");
}
arg1 = reinterpret_cast< Foo * >(argp1);
result = (Bar *)& ((arg1)->bar);
resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_Bar, 0 | 0 );
return resultobj;
fail:
return NULL;
}