diff options
Diffstat (limited to 'demo/api.py')
-rw-r--r-- | demo/api.py | 62 |
1 files changed, 62 insertions, 0 deletions
diff --git a/demo/api.py b/demo/api.py new file mode 100644 index 0000000..8cc6407 --- /dev/null +++ b/demo/api.py @@ -0,0 +1,62 @@ +import cffi +from cffi import FFI + +class PythonFFI(FFI): + + def __init__(self, backend=None): + FFI.__init__(self, backend=backend) + self._pyexports = {} + + def pyexport(self, signature): + tp = self._typeof(signature, consider_function_as_funcptr=True) + def decorator(func): + name = func.__name__ + if name in self._pyexports: + raise cffi.CDefError("duplicate pyexport'ed function %r" + % (name,)) + callback_var = self.getctype(tp, name) + self.cdef("%s;" % callback_var) + self._pyexports[name] = _PyExport(tp, func) + return decorator + + def verify(self, source='', **kwargs): + extras = [] + pyexports = sorted(self._pyexports.items()) + for name, export in pyexports: + callback_var = self.getctype(export.tp, name) + extras.append("%s;" % callback_var) + extras.append(source) + source = '\n'.join(extras) + lib = FFI.verify(self, source, **kwargs) + for name, export in pyexports: + cb = self.callback(export.tp, export.func) + export.cb = cb + setattr(lib, name, cb) + return lib + + +class _PyExport(object): + def __init__(self, tp, func): + self.tp = tp + self.func = func + + +if __name__ == '__main__': + ffi = PythonFFI() + + @ffi.pyexport("int(int)") + def add1(n): + print n + return n + 1 + + ffi.cdef(""" + int f(int); + """) + + lib = ffi.verify(""" + int f(int x) { + return add1(add1(x)); + } + """) + + assert lib.f(5) == 7 |