Смешивание ctypes и python классов в _fields_ - PullRequest
2 голосов
/ 17 апреля 2020

Я пытаюсь создать оболочку ctypes для структуры, которая использует gobject.

Структура определяется следующим образом:

struct GstMetaStruc
{
    GstMeta meta;

    GstStructure* structure;
};

GstMeta имеет существующую оболочку для самоанализа, которая предлагает мне доступ к базовому мета-объекту.

Мой текущий неправильный подход выглядит следующим образом:

import ctypes
import gi

gi.require_version("Gst", "1.0")

from gi.repository import Gst

class TcamMeta(ctypes.Structure):
    """

    """
    _fields_ = [("meta", Gst.Meta),
                ("structure", ctypes.POINTER(Gst.Structure))]

Можно ли смешивать определения ctype с существующими python классами-обертками?
Есть ли лучшие подходы для определения python классов для производных типов?

1 Ответ

1 голос
/ 17 апреля 2020

[Python 3.Docs]: ctypes - Структуры и союзы состояния ( выделение принадлежит мне):

Структуры и союзы должны быть получены из базовых классов Structure и Union , определенных в модуле ctypes . Каждый подкласс должен определять атрибут _fields_ . _fields_ должен представлять собой список 2-кортежей , содержащий имя поля и тип поля .

Тип поля должен быть типа ctypes типа c_int или любого другого производного типа ctypes : структура, объединение, массив, указатель .

Элементы _fields_ реализованы как дескрипторы , что означает, что они являются "особыми" (по сравнению с обычным членом класса). Как следствие, некоторые проверки выполняются при объявлении структуры.

>>> import ctypes as ct
>>>
>>> class A: pass
...
>>> class Stru0(ct.Structure): pass
...
>>> class Stru1(ct.Structure): _fields_ = [("c", Stru0)]
...
>>> class Stru1(ct.Structure): _fields_ = [("c", ct.c_float)]
...
>>> class Stru1(ct.Structure): _fields_ = [("c", int)]
...
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: second item in _fields_ tuple (index 0) must be a C type
>>> class Stru1(ct.Structure): _fields_ = [("c", A)]
...
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: second item in _fields_ tuple (index 0) must be a C type

Итак, если вы не получили TypeError , вы, вероятно, OK . Но, кратко взглянув на PyGObject примеров, вы не должны попадать в ситуацию, требующую этого.

...