@@ -160,13 +160,16 @@ def wrapper(name, ret, params, exported):
160160
161161def callback_setup (pname , ctype , argn ):
162162 """Returns the python source that wraps the callable pname in an
163- ffi.callback, for the C signature in ctype ("callback:void(int64_t,char*)",
164- see cffi_callback.go). The wrapper passes it on to Go as _cb_<pname>,
165- which is kept referenced by this local variable until the Go call
166- returns: cffi frees a callback as soon as nothing refers to it.
163+ ffi.callback, for the C signature in ctype
164+ ("callback:<result or void>(<parameter types>)", see cffi_callback.go).
165+ The wrapper passes it on to Go as _cb_<pname>, which is kept referenced by
166+ this local variable until the Go call returns: cffi frees a callback as
167+ soon as nothing refers to it.
168+
169+ If the callable raises, cffi prints the traceback and returns 0 to Go.
167170 """
168- cargs = ctype [len ("callback:void( " ):- 1 ]
169- ctypes = cargs .split ("," ) if cargs else [ ]
171+ ret , _ , rest = ctype [len ("callback:" ):]. partition ( "(" )
172+ ctypes = [ t for t in rest [: - 1 ] .split ("," ) if t ]
170173 names = ["a%d" % i for i in range (len (ctypes ))]
171174 conv = []
172175 for n , t in zip (names , ctypes ):
@@ -176,12 +179,23 @@ def callback_setup(pname, ctype, argn):
176179 conv .append ("bool(%s)" % n )
177180 else :
178181 conv .append (n )
179- cdecl = "void(%s)" % ", " .join ("unsigned char" if t == "bool" else t for t in ctypes )
182+ call = "%s(%s)" % (pname , ", " .join (conv ))
183+ if ret == "void" :
184+ body = call
185+ elif ret == "bool" :
186+ body = "return 1 if %s else 0" % call
187+ else :
188+ body = "return %s" % call
189+
190+ def cdecl_type (t ):
191+ return "unsigned char" if t == "bool" else t
192+
193+ cdecl = "%s(%s)" % (cdecl_type (ret ), ", " .join (cdecl_type (t ) for t in ctypes ))
180194 return "\n " .join ([
181195 " if not callable(%s):" % pname ,
182196 " raise TypeError('argument %d must be callable, not %%s' %% type(%s).__name__)" % (argn , pname ),
183197 " def _cbfn_%s(%s):" % (pname , ", " .join (names )),
184- " %s(%s) " % ( pname , ", " . join ( conv )) ,
198+ " %s" % body ,
185199 " _cb_%s = _ffi.callback(%r, _cbfn_%s)" % (pname , cdecl , pname ),
186200 ])
187201
0 commit comments