| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162 |
- 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
|