Ваш код на c ++ выглядит как классическая оболочка, использующая официальный код C-API , и это немного странно, поскольку ctypes обычно используется для использования классических типов c в python (таких как int, float и т. Д.). .).
Я лично использую C-API "один" (без ctypes), но из моего личного опыта вам не нужно беспокоиться о счетчике ссылок в этом случае, так как вы возвращаете нативный тип Python с Py_BuildValue
. Когда функция возвращает объект, владение возвращенного объекта передается вызывающей функции.
Вам следует беспокоиться о Py_XINCREF
/ Py_XDECREF
(лучше, чем Py_INCREF
/ Py_DECREF
, поскольку он принимает указатели NULL), только если вы хотите изменить владельца объекта:
Например, вы создали оболочку карты в python (назовем типизированный объект py_map). Элемент имеет класс C ++ Foo, и вы создали для них другую оболочку Python (назовем ее py_Foo). Если вы создадите функцию, которая обернет оператор [], вы собираетесь вернуть объект py_Foo в python:
F = py_Map["key"]
но так как право собственности передается вызывающей функции, вы будете вызывать деструктор при удалении F
, а карта на c ++ содержит указатель на освобожденный объект!
Решение состоит в том, чтобы написать на С ++ в оболочке []:
...
PyObject* result; // My py_Foo object
Py_XINCREF(result); // transfer the ownership
return result;
}
Вам следует взглянуть на понятие заимствованной и находящейся в собственности ссылки в python. Это важно для правильного понимания счетчика ссылок.