Я пишу собственный модуль Python в C, и мой звонок PyObject_Call
рушится. Цель - это метод экземпляра объекта, который был передан конструктору моего собственного объекта.Crash in PyObject_Call
Конструктор для моего типа пользовательского объекта выглядит следующим образом:
static int InitMyThing(EventTapObject *self, PyObject *args, PyObject *kwds) {
char *kwlist[] = { "callback", NULL };
if (!PyArg_ParseTupleAndKeywords(args, kwds, "O", kwlist, &self->callback)) {
return -1;
}
Py_INCREF(self->callback);
...
return 0;
}
Позже, в ответ на событие ОС (конкретно, OS X CGEventTap), я называю PyObject_CallObject(self->callback, NULL)
. Это, в свою очередь, вызовет PyObject_Call
, который сработает.
Я попытался позвонить PyObject_Call
напрямую (с пустым кортежем, как предписано), и он получает тот же самый сбой, что и PyObject_Print
.
Мой родной объект не удаляется в среднем времени (по крайней мере, деструктор не вызван), и ни один из них не является объектом Python, которому принадлежит метод обратного вызова.
Так что, если я звоню Py_INCREF
на обратном вызове, как он может уйти?
Когда вы говорите: «Я попытался вызвать« PyObject_Call »напрямую ... как и« PyObject_Print' », вы имеете в виду, что пытались сделать это в этой функции (в этом случае вы можете исключить возможность пересчета как имеющую отношение к делу), или вы попытались сделать это позже (в обратном вызове CF, и в этом случае перерасчет может быть релевантным - и может ли GIL/threadstate и все другие вещи)? – abarnert
Кроме того, что заставляет вас думать, что проблема заключается в том, что объект 'self' связанного метода был уничтожен, а не любые другие вещи, которые могли бы пойти не так? Просто это кажется наиболее вероятным, или некоторые доказательства, указывающие на это? – abarnert
Да, это был GIL. Мальчик, я не в курсе этих проблем с родными модулями. Вы можете отправить это как ответ, и я соглашусь с ним. – Uncommon