LINUX.ORG.RU

Вызов питоновских методов из си питоновского модуля

 ,


1

3

Есть питоновский модуль, написанный на си. Он принимает callback от питоновского кода. И когда нужно вызывает.

Но вот так работает


def cb(args):
... print("callback")

mymodule.set_callback(cb)

А вот так


class myclass(object):

.. . def cb(self, args):
......  print("callback")

.... def __init__(self):
...... mymodule.set_callback(self.cb)

Нет, в тот момент, когда должен вызваться callback происходит segfault

Из кода модуля я для вызова пробовал использовать PyObject_Call и PyObject_CallObject

★★★★★

Последнее исправление: cvs-255 (всего исправлений: 1)
Ответ на: комментарий от cvs-255

А тут self то возьмешь? Здесь нет никакой информации о self

test_ext.set_cb(self, self.conn, self.cb)

и в филдом в ту же структуру.

Linfan ★★★★★
()
Ответ на: комментарий от cvs-255

Метод это отдельный объект, который можно заменить или перекинуть другому объекту. Без указателя на парент объект, он отработает как статик.

Linfan ★★★★★
()
Ответ на: комментарий от Linfan

Я смотрел код самого питона, он сам где то у себя хранит self для переданных методов, и добавляет его при вызове

cvs-255 ★★★★★
() автор топика
Ответ на: комментарий от cvs-255

хм... попробовал - если референс на коллбек инкрементирован - self передается автоматически. Если инкрементации референса нет - self будет None. Видимо GC референс на объект удаляет еще до исполнения метода.

Linfan ★★★★★
()
Ответ на: комментарий от cvs-255

Точнее, с инкрементированным референсом self будет

<__main__.Test object at 0x7fe39aefb358>
а без инкрементации:
<bound method ExtensionFileLoader.exec_module of <bound method ModuleSpec.__init__ of <bound method _ImportLockContext.__exit__ of <bound method ModuleSpec.__init__ of <bound method FileLoader.get_data of <bound method ModuleSpec.__init__ of <bound method ModuleSpec.__init__ of <NULL>>>>>>>>

Не None в строгом смысле, но типа того :)

Linfan ★★★★★
()
Ответ на: комментарий от cvs-255

В целом интересный кейс - спасибо за обсуждение :) Коллбеки из натива в питон не попадались. Обычно python-driven логика кода.

Linfan ★★★★★
()

В первом сообщении Ъ-ванга. На любой PyObject, который ты сохраняешь себе в Си, нужно делать Py_INCREF, не важно простой объект это или callable. Bound method'ы содержат ссылку на self, поэтому объект держится пока есть ссылка на bound method переданный как callback.

ei-grad ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.