pythongstreamerctypesgobject

Mixing ctypes and python classes in _fields_


I am trying to create a ctypes wrapper for a struct that uses gobject.

The struct is defined as follows:

struct GstMetaStruc
{
    GstMeta meta;

    GstStructure* structure;
};

GstMeta has an existing introspection wrapper that offers me accress to the base meta object.

My current, wrong approach looks like this:

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))]

Is it possible to mix ctype definitions with existing python wrapper classes?
Are there better approaches to define python classes for derived types?


Solution

  • [Python 3.Docs]: ctypes - Structures and unions states (emphasis is mine):

    Structures and unions must derive from the Structure and Union base classes which are defined in the ctypes module. Each subclass must define a _fields_ attribute. _fields_ must be a list of 2-tuples, containing a field name and a field type.

    The field type must be a ctypes type like c_int, or any other derived ctypes type: structure, union, array, pointer.

    The _fields_ members are implemented as descriptors, meaning that they are "special" (compared to a regular class member). As a consequence, some checks are performed when declaring the structure.

    >>> 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
    

    So, if you didn't get a TypeError, you're probably OK. But briefly looking at PyGObject examples, you shouldn't be in the situation requiring this.