Я думаю, вы делаете вещи более сложными, чем нужно, пытаясь вызвать конструктор с указателем. Ваши методы tp_new
и tp_init
предназначены для предоставления интерфейса Python для создания экземпляра объекта. Если не имеет смысла предоставлять интерфейс Python (например, если ваш объект всегда должен быть создан с указателем C ++), просто не предоставляйте их - установите их на NULL
, и ваш объект не будет создан изPython.
В C ++ вы не ограничены этим интерфейсом. Вы можете определить свою собственную "фабричную функцию C ++", используя любые аргументы, которые вам нравятся:
PyFoo* make_PyFoo(Foo* myfoo) {
Сначала выделите ваш объект:
PyFoo *obj = (PyFoo*)(type->tp_alloc(type, 0));
# or
PyFoo *obj = PyObject_New(PyFoo, type); # use PyObject_GC_new if it has cyclic references
Два подхода в значительной степени эквивалентны, если у вас нет 't определил пользовательский распределитель. Некоторая проверка ошибок здесь опущена ....
Далее вы можете просто использовать существующий указатель Foo*
для инициализации соответствующего поля:
obj->myfoo = myfoo;
Затем просто return obj
(и закройте скобку).
Этот ответ был во многом вдохновлен моей давней неприязнью к капсулам Python. Очень редко можно увидеть разумный вариант их использования, но людям все равно нравится их использовать.