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
Post a Comment