1 $ˆl–Ðz¾”Ëm q@=q¦nõ1hß „h@q¯ÁÀÄ?÷import sys, types from .lock import allocate_lock from .error import CDefError from . import model try: callable except NameError: # Python 3.1 from collections import Callable callable = lambda x: isinstance(x, Callable) try: basestring except NameError: # Python 3.x basestring = str _unspecified = object() class FFI(object): r''' The main top-level class that you instantiate once, or once per module. Example usage: ffi = FFI() ffi.cdef(""" int printf(const char *, ...); """) C = ffi.dlopen(None) # standard library -or- C = ffi.verify() # use a C compiler: verify the decl above is right C.printf("hello, %s!\n", ffi.new("char[]", "world")) ''' def __init__(self, backend=None): """Create an FFI instance. The 'backend' argument is used to select a non-default backend, mostly for tests. """ if backend is None: # You need PyPy (>= 2.0 beta), or a CPython (>= 2.6) with # _cffi_backend.so compiled. import _cffi_backend as backend from . import __version__ if backend.__version__ != __version__: # bad version! Try to be as explicit as possible. if hasattr(backend, '__file__'): # CPython raise Exception("Version mismatch: this is the 'cffi' package version %s, located in %r. When we import the top-level '_cffi_backend' extension module, we get version %s, located in %r. The two versions should be equal; check your installation." % ( __version__, __file__, backend.__version__, backend.__file__)) else: # PyPy raise Exception("Version mismatch: this is the 'cffi' package version %s, located in %r. This interpreter comes with a built-in '_cffi_backend' module, which is version %s. The two versions should be equal; check your installation." % ( __version__, __file__, backend.__version__)) # (If you insist you can also try to pass the option # 'backend=backend_ctypes.CTypesBackend()', but don't # rely on it! It's probably not going to work well.) from . import cparser self._backend = backend self._lock = allocate_lock() self._parser = cparser.Parser() self._cached_btypes = {} self._parsed_types = types.ModuleType('parsed_types').__dict__ self._new_types = types.ModuleType('new_types').__dict__ self._function_caches = [] self._libraries = [] self._cdefsources = [] self._included_ffis = [] self._windows_unicode = None self._init_once_cache = {} self._cdef_version = None self._embedding = None self._typecache = model.get_typecache(backend) if hasattr(backend, 'set_ffi'): backend.set_ffi(self) for name in list(backend.__dict__): if name.startswith('RTLD_'): setattr(self, name, getattr(backend, name)) # with self._lock: self.BVoidP = self._get_cached_btype(model.voidp_type) self.BCharA = self._get_cached_btype(model.char_array_type) if isinstance(backend, types.ModuleType): # _cffi_backend: attach these constants to the class if not hasattr(FFI, 'NULL'): FFI.NULL = self.cast(self.BVoidP, 0) FFI.CData, FFI.CType = backend._get_types() else: # ctypes backend: attach these constants to the instance self.NULL = self.cast(self.BVoidP, 0) self.CData, self.CType = backend._get_types() self.buffer = backend.buffer def cdef(self, csource, override=False, packed=False, pack=None): """Parse the given C source. This registers all declared functions, types, and global variables. The fu