Self-referencing class: concrete python class from C interface -


i trying design c interface extended in python (using ctypes). i've used 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 want extend interface c directly:

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

but do, implement interface python using ctypes. here have 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 struggling define prototype openfunc here. technically should be:

openfunc    = ctypes.cfunctype(ctypes.pointer(python_format), ctypes.c_char_p) 

however need define python_format first, in turns requires definition openfunc.

bonus point: actual function implementation ? instance:

def func( str ): return none 

or

def func( str ): = 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 callback function 

is related other issue ? if should change initial c design, since not able return pointer python_format instance callback ?

in documentaiton ctypes.structure explains how this:

it possible define _fields_ class variable after class statement defines structure subclass, allows create data types directly or indirectly reference themselves

this means can add a:

class python_format(ctypes.structure):  # forward declaration     pass 

and after defining openfunc (and other function types):

openfunc = ctypes.cfunctype(ctypes.pointer( python_format ), ctypes.c_char_p) deletefunc = etc... 

be able define python_format._fields_ thusly:

python_format._fields_ = (     ('can_open',  canopenfunc),     ('open',      openfunc),     ('delete',    deletefunc),     ('read',      readfunc),   ) 

here's more complete example based on code:

import ctypes  class python_format(ctypes.structure):  # forward declaration     pass  canopenfunc = ctypes.pyfunctype(ctypes.c_int, ctypes.c_char_p) openfunc = ctypes.pyfunctype(ctypes.c_int,                                  ctypes.pointer(python_format),                                  ctypes.c_char_p) deletefunc = ctypes.pyfunctype(none, ctypes.c_void_p) readfunc = ctypes.pyfunctype(ctypes.c_int, ctypes.c_void_p)  def py_canopen_func(self, string):     print "py_canopen_func", string     return 1  def py_open_func(self, string):     print "py_open_func2", string     # return types callbacks cannot other simple     # datatypes (c_int, c_float, ..., c_void_p). other datatypes     # (structure, pointer, ...), ctypes returns following error     # "invalid result type callback function"     # see http://bugs.python.org/issue5710     return 1  # can't return ctypes.byref(self)  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):     python_format._fields_ = (         ('can_open', canopenfunc),         ('open', openfunc),         ('delete', deletefunc),         ('read', readfunc),       )      def __init__(self):         self.can_open = canopen_func         self.open = open_func         #self.delete = delete_func         #self.read = read_func  pf = python_format() 

Comments

Popular posts from this blog

css - SVG using textPath a symbol not rendering in Firefox -

Java 8 + Maven Javadoc plugin: Error fetching URL -

node.js - How to abort query on demand using Neo4j drivers -