2014-01-14 8 views
1

Я пишу собственный модуль 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 на обратном вызове, как он может уйти?

+0

Когда вы говорите: «Я попытался вызвать« PyObject_Call »напрямую ... как и« PyObject_Print' », вы имеете в виду, что пытались сделать это в этой функции (в этом случае вы можете исключить возможность пересчета как имеющую отношение к делу), или вы попытались сделать это позже (в обратном вызове CF, и в этом случае перерасчет может быть релевантным - и может ли GIL/threadstate и все другие вещи)? – abarnert

+0

Кроме того, что заставляет вас думать, что проблема заключается в том, что объект 'self' связанного метода был уничтожен, а не любые другие вещи, которые могли бы пойти не так? Просто это кажется наиболее вероятным, или некоторые доказательства, указывающие на это? – abarnert

+0

Да, это был GIL. Мальчик, я не в курсе этих проблем с родными модулями. Вы можете отправить это как ответ, и я соглашусь с ним. – Uncommon

ответ

1

Проблема не в том, что объект связанного метода self был уничтожен, но вы пытаетесь вызвать функцию Python, не удерживая GIL.

Обычно это первое, что нужно проверить при написании расширения C, которое выполняет код во время асинхронных обратных вызовов. Вы никогда не знаете, когда CoreFoundation (или что-то еще) назовет вас ...