Cython: приведение структуры C к объекту pythons увеличивает количество ссылок - PullRequest
1 голос
/ 20 июня 2019

Я пытаюсь привести структуру указателя C к типу объекта, при этом первое поле структуры увеличивается на 1 независимо от типа поля. Ожидается ли такое поведение, и я не должен приводить указатели C к объектам, или есть проблема с Cython?

пример кода:

C структура:

struct attr {
   int a;
};

Cython: PXD:

cdef class Attr(object):
   cdef attr * t

дарохранительница:

cdef class Attr(object):
      __init__(self):
         self.t = malloc(sizeof(attr))
         self.t.a = 0

   attr(self):
       return <object>self.t

при создании Attr и запуске метода attr поле a структуры t увеличивается (этот пример - единственный пример того, что я пытаюсь сделать неработоспособным) Спасибо за вашу помощь

1 Ответ

3 голосов
/ 20 июня 2019

Да, это ожидается.

Вероятно, вы стремитесь к тому, чтобы у Cython была возможность автоматического преобразования между структурами C и словарями Python. Это происходит без необходимости <> преобразования в коде Cython. Чтобы это работало, вы должны сообщить Cython о членах структуры. Вы должны разыменовать указатель, хотя: return self.t[0].

То, что делает приведение к <object>, говорит Cython: «этот указатель можно напрямую интерпретировать как PyObject*, и теперь мы отвечаем за его подсчет ссылок». Шаблон C API состоит в том, что у вас есть различные структуры, объявленные как начинающиеся с PyObject_HEAD. Затем вы можете привести их к PyObject* и обратно, поскольку расположение памяти в начале структуры идентично. Поскольку ваша структура не имеет этого шаблона, вы получите бессмысленные результаты.


(Приложение) Я думаю, что стоит добавить: это может стать гораздо большим бедствием, чем кажется в настоящее время. Если Python считает, что «refcount» достигает 0, то Python попытается освободить объект. Вторая часть PyObject - это указатель на PyTypeObject, который определяет тип. Целая куча вещей (например, освобождение, печать объекта, практически любое взаимодействие с ним из Python) может заставить Python попытаться найти объект этого типа, и поскольку структура не содержит указатель на действительный PyTypeObject, то это в конечном итоге потерпит крах.

...