summaryrefslogtreecommitdiff
path: root/demo/api.py
diff options
context:
space:
mode:
Diffstat (limited to 'demo/api.py')
-rw-r--r--demo/api.py62
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