Обернутый SWIG объект C++ удален преждевременноPython

Программы на Python
Anonymous
Обернутый SWIG объект C++ удален преждевременно

Сообщение Anonymous »

У меня есть класс C++, завернутый с помощью SWIG, поэтому к нему можно получить доступ из Python. До определенного момента это работает, но в этом коде происходит сбой:

Код: Выделить всё

libs = ['lib1', 'lib2']
for libname in libs :
lib = library(libname)
lib.dbOpenLib('./'+libname)
... do something with library list
Здесь «библиотека» — это класс C++, а в dbOpenLib мы добавляем библиотеку в глобальный список открытых библиотек. Сбой происходит из-за того, что библиотека('lib1') удаляется после первого прохода цикла for.
Я нашел этот ответ, который, кажется, решает проблему. Итак, в классе библиотеки я добавил:

Код: Выделить всё

public:
PyObject *obj;
void incref() { Py_INCREF(obj); }
void decref() { Py_DECREF(obj); }
и в конструкторе библиотеки добавлено:

Код: Выделить всё

obj = new PyObject;
Об этом не упоминалось в ответе выше, но без инициализации «obj» не определен. Хотя я ожидал, что он будет инициализирован в приведенной ниже карте типов.
Затем в своем коде SWIG я добавил:

Код: Выделить всё

%typemap(out) cdb::library * {
result->obj = $result = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_cdb__library, SWIG_POINTER_NEW |  0 );
}
т.е. установите 'obj' при создании новой библиотеки.
Наконец, моя функция dbOpenLib() имеет incref() в библиотеке. При трассировке с помощью отладчика значение refcnt объекта obj увеличивается при создании новой библиотеки.
Но библиотека по-прежнему удаляется, как только выходит за пределы области действия, и неясно, чего мне не хватает. Где Python решает удалить «lib» - требуются ли какие-либо другие изменения, например. проверить ссылку «obj» перед удалением библиотеки, и если да, то где?

Подробнее здесь: https://stackoverflow.com/questions/798 ... rematurely

Вернуться в «Python»