1. This site uses cookies. By continuing to use this site, you are agreeing to our use of cookies. Learn More.
  2. Anuncie Aqui
    Anuncie aqui você Também: fdantas@4each.com.br

[Python] Self-referencing class: concrete python class from C interface

Discussão em 'Python' iniciado por Stack, Setembro 17, 2025.

  1. Stack

    Stack Membro Participativo

    I am trying to design a C interface which could easily be extended in Python (using ctypes). I've used the natural idiom in C:

    struct format {
    int (*can_open)(const char *filename);
    struct format * (*open)(const char *filename);
    void (*delete)(struct format *self);
    int (*read)(struct format *self, char *buf, size_t len);
    };


    It works nicely if I want to extend this interface from C directly:

    struct derived /* concrete implementation */
    {
    struct format base;
    };


    But what I would really like to do, is implement this interface from Python using ctypes. Here is what I have so far:

    CANOPENFUNC = ctypes.CFUNCTYPE(ctypes.c_int, ctypes.c_char_p)
    #OPENFUNC = ctypes.CFUNCTYPE(ctypes.c_void_p, ctypes.c_char_p)
    #OPENFUNC = ctypes.CFUNCTYPE(ctypes.POINTER( python_format ), ctypes.c_char_p)
    #DELETEFUNC = ctypes.CFUNCTYPE(None, ctypes.c_void_p)
    #READFUNC = ctypes.CFUNCTYPE(ctypes.c_int, ctypes.c_void_p)

    def py_canopen_func( string ):
    print "py_canopen_func", string
    return 1

    canopen_func = CANOPENFUNC(py_canopen_func)
    #open_func = OPENFUNC( py_open_func)
    #delete_func = DELETEFUNC(py_canopen_func)
    #read_func = READFUNC(py_canopen_func)

    class python_format(ctypes.Structure):
    _fields_ = (
    ('can_open', CANOPENFUNC),
    ('open', OPENFUNC),
    ('delete', DELETEFUNC),
    ('read', READFUNC),
    )
    def __init__(self):
    self.can_open = canopen_func
    OPENFUNC = ctypes.CFUNCTYPE(ctypes.POINTER(python_format), ctypes.c_char_p)
    def py_open_func2( string ):
    print "py_open_func2", string
    return ctypes.byref(self)
    self.open = OPENFUNC( py_open_func2 )
    #self.delete = delete_func
    #self.read = read_func


    Really I am struggling to define the prototype for OPENFUNC here. Technically it should be:

    OPENFUNC = ctypes.CFUNCTYPE(ctypes.POINTER(python_format), ctypes.c_char_p)


    However I need to define python_format first, which in turns requires a definition for OPENFUNC.

    Bonus point: what would be an actual function implementation ? For instance:

    def func( str ): return None


    or

    def func( str ): i = python_format(); return ctypes.pointer(i)


    both gives me:

    class python_format(ctypes.Structure):
    pass
    OPENFUNC = ctypes.CFUNCTYPE(ctypes.POINTER( python_format ), ctypes.c_char_p)
    OPENFUNC( func )
    Traceback (most recent call last):
    File "<stdin>", line 1, in <module>
    TypeError: invalid result type for callback function


    Is this related to this other issue ? If so should I change my initial C design, since I will not be able to return a pointer to a python_format instance from a callback ?

    Continue reading...

Compartilhe esta Página