我们从Python开源项目中,提取了以下50个代码示例,用于说明如何使用cffi.FFI。
def cast_int_addr(n): """Cast an address to a Python int This could be a Python integer or a CFFI pointer """ if isinstance(n, (int, long)): return n try: import cffi except ImportError: pass else: # from pyzmq, this is an FFI void * ffi = cffi.FFI() if isinstance(n, ffi.CData): return int(ffi.cast("size_t", n)) raise ValueError("Cannot cast %r to int" % n)
def compile_extension(name, header, sources=[], verbose=True, with_cuda=False, **kwargs): name, target_dir = _create_module_dir(name) cffi_wrapper_name = '_' + name wrapper_source, include_dirs = _setup_wrapper(with_cuda) include_dirs.extend(kwargs.pop('include_dirs', [])) with open(header, 'r') as f: header_source = f.read() ffi = cffi.FFI() sources = [os.path.abspath(src) for src in sources] ffi.set_source(cffi_wrapper_name, wrapper_source + header_source, sources=sources, include_dirs=include_dirs, **kwargs) ffi.cdef(_typedefs + header_source); _build_extension(ffi, cffi_wrapper_name, target_dir, verbose) _make_python_wrapper(name, cffi_wrapper_name, target_dir)
def test_import_from_lib(self): ffi2 = cffi.FFI() ffi2.cdef("int myfunc(int); int myvar;\n#define MYFOO ...\n") outputfilename = recompile(ffi2, "_test_import_from_lib", "int myfunc(int x) { return x + 1; }\n" "int myvar = -5;\n" "#define MYFOO 42", tmpdir=str(udir)) imp.load_dynamic("_test_import_from_lib", outputfilename) from _test_import_from_lib.lib import myfunc, myvar, MYFOO assert MYFOO == 42 assert myfunc(43) == 44 assert myvar == -5 # but can't be changed, so not very useful py.test.raises(ImportError, "from _test_import_from_lib.lib import bar") d = {} exec("from _test_import_from_lib.lib import *", d) assert (set(key for key in d if not key.startswith('_')) == set(['myfunc', 'MYFOO'])) # # also test "import *" on the module itself, which should be # equivalent to "import ffi, lib" d = {} exec("from _test_import_from_lib import *", d) assert (sorted([x for x in d.keys() if not x.startswith('__')]) == ['ffi', 'lib'])
def test_include_1(): sub_ffi = FFI() sub_ffi.cdef("static const int k2 = 121212;") sub_ffi.include(original_ffi) assert 'macro FOOBAR' in original_ffi._parser._declarations assert 'macro FOOBAZ' in original_ffi._parser._declarations sub_ffi.set_source('re_python_pysrc', None) sub_ffi.emit_python_code(str(tmpdir.join('_re_include_1.py'))) # if sys.version_info[:2] >= (3, 3): import importlib importlib.invalidate_caches() # issue 197 (but can't reproduce myself) # from _re_include_1 import ffi assert ffi.integer_const('FOOBAR') == -42 assert ffi.integer_const('FOOBAZ') == -43 assert ffi.integer_const('k2') == 121212 lib = ffi.dlopen(extmod) # <- a random unrelated library would be fine assert lib.FOOBAR == -42 assert lib.FOOBAZ == -43 assert lib.k2 == 121212 # p = ffi.new("bar_t *", [5, b"foobar"]) assert p.a[4] == ord('a')
def test_api_compile_explicit_target_3(self): ffi = cffi.FFI() ffi.set_source("mod_name_in_package.mymod", "/*code would be here*/") x = ffi.compile(target="foo.bar.baz") if sys.platform != 'win32': self.check_produced_files({ 'mod_name_in_package': {'foo.bar.baz': None, 'mymod.c': None, 'mymod.o': None}}) sofile = os.path.join(str(self.udir), 'mod_name_in_package', 'foo.bar.baz') assert os.path.isabs(x) and os.path.samefile(x, sofile) else: self.check_produced_files({ 'mod_name_in_package': {'foo.bar.baz': None, 'mymod.c': None}, 'Release': '?'})
def _make_distutils_api(self): os.mkdir("src") os.mkdir(os.path.join("src", "pack1")) with open(os.path.join("src", "pack1", "__init__.py"), "w") as f: pass with open("setup.py", "w") as f: f.write("""if 1: import cffi ffi = cffi.FFI() ffi.set_source("pack1.mymod", "/*code would be here*/") from distutils.core import setup setup(name='example1', version='0.1', packages=['pack1'], package_dir={'': 'src'}, ext_modules=[ffi.distutils_extension()]) """)
def _make_setuptools_abi(self): self._prepare_setuptools() os.mkdir("src0") os.mkdir(os.path.join("src0", "pack2")) with open(os.path.join("src0", "pack2", "__init__.py"), "w") as f: pass with open(os.path.join("src0", "pack2", "_build.py"), "w") as f: f.write("""if 1: import cffi ffi = cffi.FFI() ffi.set_source("pack2.mymod", None) """) with open("setup.py", "w") as f: f.write("""if 1: from setuptools import setup setup(name='example1', version='0.1', packages=['pack2'], package_dir={'': 'src0'}, cffi_modules=["src0/pack2/_build.py:ffi"]) """)
def test_struct_included(): baseffi = FFI() baseffi.cdef("struct foo_s { int x; };") baseffi.set_source('test_struct_included_base', None) # ffi = FFI() ffi.include(baseffi) target = udir.join('test_struct_included.py') make_py_source(ffi, 'test_struct_included', str(target)) assert target.read() == r"""# auto-generated file import _cffi_backend from test_struct_included_base import ffi as _ffi0 ffi = _cffi_backend.FFI('test_struct_included', _version = 0x2601, _types = b'\x00\x00\x00\x09', _struct_unions = ((b'\x00\x00\x00\x00\x00\x00\x00\x08foo_s',),), _includes = (_ffi0,), ) """
def test_global_var_int(): ffi = FFI() ffi.cdef("int a, b, c;") lib = verify(ffi, 'test_global_var_int', 'int a = 999, b, c;') assert lib.a == 999 lib.a -= 1001 assert lib.a == -2 lib.a = -2147483648 assert lib.a == -2147483648 py.test.raises(OverflowError, "lib.a = 2147483648") py.test.raises(OverflowError, "lib.a = -2147483649") lib.b = 525 # try with the first access being in setattr, too assert lib.b == 525 py.test.raises(AttributeError, "del lib.a") py.test.raises(AttributeError, "del lib.c") py.test.raises(AttributeError, "del lib.foobarbaz")
def test_dir(): ffi = FFI() ffi.cdef("int ff(int); int aa; static const int my_constant;") lib = verify(ffi, 'test_dir', """ #define my_constant (-45) int aa; int ff(int x) { return x+aa; } """) lib.aa = 5 assert dir(lib) == ['aa', 'ff', 'my_constant'] # aaobj = lib.__dict__['aa'] assert not isinstance(aaobj, int) # some internal object instead assert lib.__dict__ == { 'ff': lib.ff, 'aa': aaobj, 'my_constant': -45} lib.__dict__['ff'] = "??" assert lib.ff(10) == 15
def test_verify_struct(): ffi = FFI() ffi.cdef("""struct foo_s { int b; short a; ...; }; struct bar_s { struct foo_s *f; };""") lib = verify(ffi, 'test_verify_struct', """struct foo_s { short a; int b; }; struct bar_s { struct foo_s *f; };""") ffi.typeof("struct bar_s *") p = ffi.new("struct foo_s *", {'a': -32768, 'b': -2147483648}) assert p.a == -32768 assert p.b == -2147483648 py.test.raises(OverflowError, "p.a -= 1") py.test.raises(OverflowError, "p.b -= 1") q = ffi.new("struct bar_s *", {'f': p}) assert q.f == p # assert ffi.offsetof("struct foo_s", "a") == 0 assert ffi.offsetof("struct foo_s", "b") == 4 assert ffi.offsetof(u+"struct foo_s", u+"b") == 4 # py.test.raises(TypeError, ffi.addressof, p) assert ffi.addressof(p[0]) == p assert ffi.typeof(ffi.addressof(p[0])) is ffi.typeof("struct foo_s *") assert ffi.typeof(ffi.addressof(p, "b")) is ffi.typeof("int *") assert ffi.addressof(p, "b")[0] == p.b
def test_type_caching(): ffi1 = FFI(); ffi1.cdef("struct foo_s;") ffi2 = FFI(); ffi2.cdef("struct foo_s;") # different one! lib1 = verify(ffi1, 'test_type_caching_1', 'struct foo_s;') lib2 = verify(ffi2, 'test_type_caching_2', 'struct foo_s;') # shared types assert ffi1.typeof("long") is ffi2.typeof("long") assert ffi1.typeof("long**") is ffi2.typeof("long * *") assert ffi1.typeof("long(*)(int, ...)") is ffi2.typeof("long(*)(int, ...)") # non-shared types assert ffi1.typeof("struct foo_s") is not ffi2.typeof("struct foo_s") assert ffi1.typeof("struct foo_s *") is not ffi2.typeof("struct foo_s *") assert ffi1.typeof("struct foo_s*(*)()") is not ( ffi2.typeof("struct foo_s*(*)()")) assert ffi1.typeof("void(*)(struct foo_s*)") is not ( ffi2.typeof("void(*)(struct foo_s*)"))
def test_module_name_in_package(): ffi = FFI() ffi.cdef("int foo(int);") recompiler.recompile(ffi, "test_module_name_in_package.mymod", "int foo(int x) { return x + 32; }", tmpdir=str(udir)) old_sys_path = sys.path[:] try: package_dir = udir.join('test_module_name_in_package') for name in os.listdir(str(udir)): assert not name.startswith('test_module_name_in_package.') assert os.path.isdir(str(package_dir)) assert len(os.listdir(str(package_dir))) > 0 assert os.path.exists(str(package_dir.join('mymod.c'))) package_dir.join('__init__.py').write('') # sys.path.insert(0, str(udir)) import test_module_name_in_package.mymod assert test_module_name_in_package.mymod.lib.foo(10) == 42 assert test_module_name_in_package.mymod.__name__ == ( 'test_module_name_in_package.mymod') finally: sys.path[:] = old_sys_path
def test_include_2(): ffi1 = FFI() ffi1.cdef("struct foo_s { int x, y; };") verify(ffi1, "test_include_2_parent", "struct foo_s { int x, y; };") ffi = FFI() ffi.include(ffi1) ffi.cdef("struct foo_s *ff2(struct foo_s *);") lib = verify(ffi, "test_include_2", "struct foo_s { int x, y; }; //usually from a #include\n" "struct foo_s *ff2(struct foo_s *p) { p->y++; return p; }") p = ffi.new("struct foo_s *") p.y = 41 q = lib.ff2(p) assert q == p assert p.y == 42 assert ffi1.typeof("struct foo_s") is ffi.typeof("struct foo_s")
def test_include_5(): ffi1 = FFI() ffi1.cdef("typedef struct { int x[2]; int y; } *mystruct_p;") verify(ffi1, "test_include_5_parent", "typedef struct { int x[2]; int y; } *mystruct_p;") ffi = FFI() ffi.include(ffi1) ffi.cdef("mystruct_p ff5(mystruct_p);") lib = verify(ffi, "test_include_5", "typedef struct {int x[2]; int y; } *mystruct_p; //usually #include\n" "mystruct_p ff5(mystruct_p p) { p->x[1] += 42; return p; }") assert ffi.alignof(ffi.typeof("mystruct_p").item) == 4 assert ffi1.typeof("mystruct_p") is ffi.typeof("mystruct_p") p = ffi.new("mystruct_p", [[5, 10], -17]) q = lib.ff5(p) assert q == p assert p.x[0] == 5 assert p.x[1] == 52 assert p.y == -17 assert ffi.alignof(ffi.typeof(p[0])) == 4
def test_include_6(): ffi1 = FFI() ffi1.cdef("typedef ... mystruct_t;") verify(ffi1, "test_include_6_parent", "typedef struct _mystruct_s mystruct_t;") ffi = FFI() ffi.include(ffi1) ffi.cdef("mystruct_t *ff6(void); int ff6b(mystruct_t *);") lib = verify(ffi, "test_include_6", "typedef struct _mystruct_s mystruct_t; //usually from a #include\n" "struct _mystruct_s { int x; };\n" "static mystruct_t result_struct = { 42 };\n" "mystruct_t *ff6(void) { return &result_struct; }\n" "int ff6b(mystruct_t *p) { return p->x; }") p = lib.ff6() assert ffi.cast("int *", p)[0] == 42 assert lib.ff6b(p) == 42
def test_include_7(): ffi1 = FFI() ffi1.cdef("typedef ... mystruct_t;\n" "int ff7b(mystruct_t *);") verify(ffi1, "test_include_7_parent", "typedef struct { int x; } mystruct_t;\n" "int ff7b(mystruct_t *p) { return p->x; }") ffi = FFI() ffi.include(ffi1) ffi.cdef("mystruct_t *ff7(void);") lib = verify(ffi, "test_include_7", "typedef struct { int x; } mystruct_t; //usually from a #include\n" "static mystruct_t result_struct = { 42 };" "mystruct_t *ff7(void) { return &result_struct; }") p = lib.ff7() assert ffi.cast("int *", p)[0] == 42 assert lib.ff7b(p) == 42
def test_unicode_libraries(): try: unicode except NameError: py.test.skip("for python 2.x") # import math lib_m = "m" if sys.platform == 'win32': #there is a small chance this fails on Mingw via environ $CC import distutils.ccompiler if distutils.ccompiler.get_default_compiler() == 'msvc': lib_m = 'msvcrt' ffi = FFI() ffi.cdef(unicode("float sin(double); double cos(double);")) lib = verify(ffi, 'test_math_sin_unicode', unicode('#include <math.h>'), libraries=[unicode(lib_m)]) assert lib.cos(1.43) == math.cos(1.43)
def test_incomplete_struct_as_both(): ffi = FFI() ffi.cdef("struct foo_s { int x; ...; }; struct bar_s { int y; ...; };\n" "struct foo_s f(int, struct bar_s);") lib = verify(ffi, "test_incomplete_struct_as_both", "struct foo_s { int a, x, z; };\n" "struct bar_s { int b, c, y, d; };\n" "struct foo_s f(int x, struct bar_s b) {\n" " struct foo_s r; r.x = x * b.y; return r;\n" "}") b = ffi.new("struct bar_s *", [7]) s = lib.f(6, b[0]) assert s.x == 42 assert ffi.typeof(lib.f) == ffi.typeof( "struct foo_s(*)(int, struct bar_s)") s = lib.f(14, {'y': -3}) assert s.x == -42
def test_issue198(): ffi = FFI() ffi.cdef(""" typedef struct{...;} opaque_t; const opaque_t CONSTANT; int toint(opaque_t); """) lib = verify(ffi, 'test_issue198', """ typedef int opaque_t; #define CONSTANT ((opaque_t)42) static int toint(opaque_t o) { return o; } """) def random_stuff(): pass assert lib.toint(lib.CONSTANT) == 42 random_stuff() assert lib.toint(lib.CONSTANT) == 42
def test_some_float_type(): ffi = FFI() ffi.cdef(""" typedef double... foo_t; typedef float... bar_t; foo_t sum(foo_t[]); bar_t neg(bar_t); """) lib = verify(ffi, 'test_some_float_type', """ typedef float foo_t; static foo_t sum(foo_t x[]) { return x[0] + x[1]; } typedef double bar_t; static double neg(double x) { return -x; } """) assert lib.sum([40.0, 2.25]) == 42.25 assert lib.sum([12.3, 45.6]) != 12.3 + 45.6 # precision loss assert lib.neg(12.3) == -12.3 # no precision loss assert ffi.sizeof("foo_t") == ffi.sizeof("float") assert ffi.sizeof("bar_t") == ffi.sizeof("double")
def test_extern_python_bogus_name(): ffi = FFI() ffi.cdef("int abc;") lib = verify(ffi, 'test_extern_python_bogus_name', "int abc;") def fn(): pass py.test.raises(ffi.error, ffi.def_extern("unknown_name"), fn) py.test.raises(ffi.error, ffi.def_extern("abc"), fn) assert lib.abc == 0 e = py.test.raises(ffi.error, ffi.def_extern("abc"), fn) assert str(e.value) == ("ffi.def_extern('abc'): no 'extern \"Python\"' " "function with this name") e = py.test.raises(ffi.error, ffi.def_extern(), fn) assert str(e.value) == ("ffi.def_extern('fn'): no 'extern \"Python\"' " "function with this name") # py.test.raises(TypeError, ffi.def_extern(42), fn) py.test.raises((TypeError, AttributeError), ffi.def_extern(), "foo") class X: pass x = X() x.__name__ = x py.test.raises(TypeError, ffi.def_extern(), x)
def test_callback_onerror(self): ffi = FFI(backend=self.Backend()) seen = [] def oops(*args): seen.append(args) def otherfunc(): raise LookupError def cb(n): otherfunc() a = ffi.callback("int(*)(int)", cb, error=42, onerror=oops) res = a(234) assert res == 42 assert len(seen) == 1 exc, val, tb = seen[0] assert exc is LookupError assert isinstance(val, LookupError) assert tb.tb_frame.f_code.co_name == 'cb' assert tb.tb_frame.f_locals['n'] == 234
def test_ffi_new_allocator_4(self): ffi = FFI(backend=self.Backend()) py.test.raises(TypeError, ffi.new_allocator, free=lambda x: None) # def myalloc2(size): raise LookupError alloc2 = ffi.new_allocator(myalloc2) py.test.raises(LookupError, alloc2, "int[5]") # def myalloc3(size): return 42 alloc3 = ffi.new_allocator(myalloc3) e = py.test.raises(TypeError, alloc3, "int[5]") assert str(e.value) == "alloc() must return a cdata object (got int)" # def myalloc4(size): return ffi.cast("int", 42) alloc4 = ffi.new_allocator(myalloc4) e = py.test.raises(TypeError, alloc4, "int[5]") assert str(e.value) == "alloc() must return a cdata pointer, not 'int'" # def myalloc5(size): return ffi.NULL alloc5 = ffi.new_allocator(myalloc5) py.test.raises(MemoryError, alloc5, "int[5]")
def test_integer_ranges(self): ffi = FFI(backend=self.Backend()) for (c_type, size) in [('char', 1), ('short', 2), ('short int', 2), ('', 4), ('int', 4), ('long', SIZE_OF_LONG), ('long int', SIZE_OF_LONG), ('long long', 8), ('long long int', 8), ]: for unsigned in [None, False, True]: c_decl = {None: '', False: 'signed ', True: 'unsigned '}[unsigned] + c_type if c_decl == 'char' or c_decl == '': continue self._test_int_type(ffi, c_decl, size, unsigned)
def test_new_array_args(self): ffi = FFI(backend=self.Backend()) # this tries to be closer to C: where we say "int x[5] = {10, 20, ..}" # then here we must enclose the items in a list p = ffi.new("int[5]", [10, 20, 30, 40, 50]) assert p[0] == 10 assert p[1] == 20 assert p[2] == 30 assert p[3] == 40 assert p[4] == 50 p = ffi.new("int[4]", [25]) assert p[0] == 25 assert p[1] == 0 # follow C convention rather than LuaJIT's assert p[2] == 0 assert p[3] == 0 p = ffi.new("int[4]", [ffi.cast("int", -5)]) assert p[0] == -5 assert repr(p) == "<cdata 'int[4]' owning %d bytes>" % (4*SIZE_OF_INT)
def test_new_array_varsize(self): ffi = FFI(backend=self.Backend()) p = ffi.new("int[]", 10) # a single integer is the length assert p[9] == 0 py.test.raises(IndexError, "p[10]") # py.test.raises(TypeError, ffi.new, "int[]") # p = ffi.new("int[]", [-6, -7]) # a list is all the items, like C assert p[0] == -6 assert p[1] == -7 py.test.raises(IndexError, "p[2]") assert repr(p) == "<cdata 'int[]' owning %d bytes>" % (2*SIZE_OF_INT) # p = ffi.new("int[]", 0) py.test.raises(IndexError, "p[0]") py.test.raises(ValueError, ffi.new, "int[]", -1) assert repr(p) == "<cdata 'int[]' owning 0 bytes>"
def test_float(self): ffi = FFI(backend=self.Backend()) p = ffi.new("float[]", [-2, -2.5]) assert p[0] == -2.0 assert p[1] == -2.5 p[1] += 17.75 assert p[1] == 15.25 # p = ffi.new("float*", 15.75) assert p[0] == 15.75 py.test.raises(TypeError, int, p) py.test.raises(TypeError, float, p) p[0] = 0.0 assert bool(p) is True # p = ffi.new("float*", 1.1) f = p[0] assert f != 1.1 # because of rounding effect assert abs(f - 1.1) < 1E-7 # INF = 1E200 * 1E200 assert 1E200 != INF p[0] = 1E200 assert p[0] == INF # infinite, not enough precision
def test_pointer_to_struct(self): ffi = FFI(backend=self.Backend()) ffi.cdef("struct foo { int a; short b, c; };") s = ffi.new("struct foo *") s.a = -42 assert s[0].a == -42 p = ffi.new("struct foo **", s) assert p[0].a == -42 assert p[0][0].a == -42 p[0].a = -43 assert s.a == -43 assert s[0].a == -43 p[0][0].a = -44 assert s.a == -44 assert s[0].a == -44 s.a = -45 assert p[0].a == -45 assert p[0][0].a == -45 s[0].a = -46 assert p[0].a == -46 assert p[0][0].a == -46
def test_sizeof_type(self): ffi = FFI(backend=self.Backend()) ffi.cdef(""" struct foo { int a; short b, c, d; }; union foo { int a; short b, c, d; }; """) for c_type, expected_size in [ ('char', 1), ('unsigned int', 4), ('char *', SIZE_OF_PTR), ('int[5]', 20), ('struct foo', 12), ('union foo', 4), ]: size = ffi.sizeof(c_type) assert size == expected_size, (size, expected_size, ctype)
def test_string_from_char_array(self): ffi = FFI(backend=self.Backend()) p = ffi.new("char[]", b"hello.") p[5] = b'!' assert ffi.string(p) == b"hello!" p[6] = b'?' assert ffi.string(p) == b"hello!?" p[3] = b'\x00' assert ffi.string(p) == b"hel" assert ffi.string(p, 2) == b"he" py.test.raises(IndexError, "p[7] = b'X'") # a = ffi.new("char[]", b"hello\x00world") assert len(a) == 12 p = ffi.cast("char *", a) assert ffi.string(p) == b'hello'
def test_functionptr_simple(self): ffi = FFI(backend=self.Backend()) py.test.raises(TypeError, ffi.callback, "int(*)(int)", 0) def cb(n): return n + 1 cb.__qualname__ = 'cb' p = ffi.callback("int(*)(int)", cb) res = p(41) # calling an 'int(*)(int)', i.e. a function pointer assert res == 42 and type(res) is int res = p(ffi.cast("int", -41)) assert res == -40 and type(res) is int assert repr(p).startswith( "<cdata 'int(*)(int)' calling <function cb at 0x") assert ffi.typeof(p) is ffi.typeof("int(*)(int)") q = ffi.new("int(**)(int)", p) assert repr(q) == "<cdata 'int(* *)(int)' owning %d bytes>" % ( SIZE_OF_PTR) py.test.raises(TypeError, "q(43)") res = q[0](43) assert res == 44 q = ffi.cast("int(*)(int)", p) assert repr(q).startswith("<cdata 'int(*)(int)' 0x") res = q(45) assert res == 46
def test_functionptr_intptr_return(self): ffi = FFI(backend=self.Backend()) def cb(): return ffi.NULL p = ffi.callback("int*(*)()", cb) res = p() assert res == ffi.NULL int_ptr = ffi.new('int*') def cb(): return int_ptr p = ffi.callback("int*(*)()", cb) res = p() assert repr(res).startswith("<cdata 'int *' 0x") assert res == int_ptr int_array_ptr = ffi.new('int[1]') def cb(): return int_array_ptr p = ffi.callback("int*(*)()", cb) res = p() assert repr(res).startswith("<cdata 'int *' 0x") assert res == int_array_ptr
def test_cast_float(self): ffi = FFI(backend=self.Backend()) a = ffi.cast("float", 12) assert float(a) == 12.0 a = ffi.cast("float", 12.5) assert float(a) == 12.5 a = ffi.cast("float", b"A") assert float(a) == ord("A") a = ffi.cast("int", 12.9) assert int(a) == 12 a = ffi.cast("char", 66.9 + 256) assert ffi.string(a) == b"B" # a = ffi.cast("float", ffi.cast("int", 12)) assert float(a) == 12.0 a = ffi.cast("float", ffi.cast("double", 12.5)) assert float(a) == 12.5 a = ffi.cast("float", ffi.cast("char", b"A")) assert float(a) == ord("A") a = ffi.cast("int", ffi.cast("double", 12.9)) assert int(a) == 12 a = ffi.cast("char", ffi.cast("double", 66.9 + 256)) assert ffi.string(a) == b"B"
def test_enum(self): ffi = FFI(backend=self.Backend()) ffi.cdef("enum foo { A0, B0, CC0, D0 };") assert ffi.string(ffi.cast("enum foo", 0)) == "A0" assert ffi.string(ffi.cast("enum foo", 2)) == "CC0" assert ffi.string(ffi.cast("enum foo", 3)) == "D0" assert ffi.string(ffi.cast("enum foo", 4)) == "4" ffi.cdef("enum bar { A1, B1=-2, CC1, D1, E1 };") assert ffi.string(ffi.cast("enum bar", 0)) == "A1" assert ffi.string(ffi.cast("enum bar", -2)) == "B1" assert ffi.string(ffi.cast("enum bar", -1)) == "CC1" assert ffi.string(ffi.cast("enum bar", 1)) == "E1" assert ffi.cast("enum bar", -2) != ffi.cast("enum bar", -2) assert ffi.cast("enum foo", 0) != ffi.cast("enum bar", 0) assert ffi.cast("enum bar", 0) != ffi.cast("int", 0) assert repr(ffi.cast("enum bar", -1)) == "<cdata 'enum bar' -1: CC1>" assert repr(ffi.cast("enum foo", -1)) == ( # enums are unsigned, if "<cdata 'enum foo' 4294967295>") # they contain no neg value ffi.cdef("enum baz { A2=0x1000, B2=0x2000 };") assert ffi.string(ffi.cast("enum baz", 0x1000)) == "A2" assert ffi.string(ffi.cast("enum baz", 0x2000)) == "B2"
def test_enum_in_struct(self): ffi = FFI(backend=self.Backend()) ffi.cdef("enum foo { A, B, C, D }; struct bar { enum foo e; };") s = ffi.new("struct bar *") s.e = 0 assert s.e == 0 s.e = 3 assert s.e == 3 assert s[0].e == 3 s[0].e = 2 assert s.e == 2 assert s[0].e == 2 s.e = ffi.cast("enum foo", -1) assert s.e == 4294967295 assert s[0].e == 4294967295 s.e = s.e py.test.raises(TypeError, "s.e = 'B'") py.test.raises(TypeError, "s.e = '2'") py.test.raises(TypeError, "s.e = '#2'") py.test.raises(TypeError, "s.e = '#7'")
def __init__(self): # Store these on the class since they should only ever be called once if _LibUUID._ffi is None or _LibUUID._libuuid is None: _LibUUID._ffi = FFI() # These definitions are from uuid.h _LibUUID._ffi.cdef(""" typedef unsigned char uuid_t[16]; void uuid_generate(uuid_t out); void uuid_generate_random(uuid_t out); void uuid_generate_time(uuid_t out); """) # By opening the library with dlopen, the compile step is skipped # dodging a class of errors, since headers aren't needed, just the # installed library. _LibUUID._libuuid = _LibUUID._ffi.dlopen( ctypes.util.find_library("uuid") ) get_config().logger.debug( "FastUUID Created - FFI: ({}), LIBUUID: ({})".format( _LibUUID._ffi, _LibUUID._libuuid ) ) # Keeping only one copy of this around does result in # pretty substantial performance improvements - in the 10,000s of # messages per second range self.output = _LibUUID._ffi.new("uuid_t")
def check_lib_python_found(tmpdir): global _link_error if _link_error == '?': ffi = cffi.FFI() kwds = {} ffi._apply_embedding_fix(kwds) ffi.set_source("_test_lib_python_found", "", **kwds) try: ffi.compile(tmpdir=tmpdir, verbose=True) except cffi.VerificationError as e: _link_error = e else: _link_error = None if _link_error: py.test.skip(str(_link_error))
def test_multiple_independent_structs(self): CDEF2 = "struct ab { int x; };" ffi2 = cffi.FFI(); ffi2.cdef(CDEF2) outputfilename = recompile(ffi2, "test_multiple_independent_structs", CDEF2, tmpdir=str(udir)) module = imp.load_dynamic("test_multiple_independent_structs", outputfilename) ffi1 = module.ffi foo1 = ffi1.new("struct ab *", [10]) foo2 = ffi .new("struct ab *", [20, 30]) assert foo1.x == 10 assert foo2.a == 20 assert foo2.b == 30
def test_include_struct_union_enum_typedef(self): ffi1, CCODE = construction_params ffi2 = cffi.FFI() ffi2.include(ffi1) outputfilename = recompile(ffi2, "test_include_struct_union_enum_typedef", CCODE, tmpdir=str(udir)) module = imp.load_dynamic("test_include_struct_union_enum_typedef", outputfilename) ffi2 = module.ffi # p = ffi2.new("struct nonpacked *", [b'A', -43141]) assert p.a == b'A' assert p.b == -43141 # p = ffi.new("union simple_u *", [-52525]) assert p.a == -52525 # p = ffi.cast("enum foq", 2) assert ffi.string(p) == "cffiCC0" assert ffi2.sizeof("char[cffiCC0]") == 2 # p = ffi.new("anon_foo_t *", [-52526]) assert p.a == -52526 p = ffi.new("named_foo_p", [-52527]) assert p.a == -52527
def test_emit_c_code(self): ffi = cffi.FFI() ffi.set_source("foobar", "??") c_file = str(udir.join('test_emit_c_code')) ffi.emit_c_code(c_file) assert os.path.isfile(c_file)
def test_function(): import _cffi_backend from re_python_pysrc import ffi lib = ffi.dlopen(extmod) assert lib.add42(-10) == 32 assert type(lib.add42) is _cffi_backend.FFI.CData
def test_function_with_varargs(): import _cffi_backend from re_python_pysrc import ffi lib = ffi.dlopen(extmod, 0) assert lib.add43(45, ffi.cast("int", -5)) == 45 assert type(lib.add43) is _cffi_backend.FFI.CData
def test_check_version(): import _cffi_backend e = py.test.raises(ImportError, _cffi_backend.FFI, "foobar", _version=0x2594) assert str(e.value).startswith( "cffi out-of-line Python module 'foobar' has unknown version")
def test_partial_enum(): ffi = FFI() ffi.cdef("enum foo { A, B, ... };") ffi.set_source('test_partial_enum', None) py.test.raises(VerificationMissing, ffi.emit_python_code, str(tmpdir.join('test_partial_enum.py')))
def test_abi_emit_python_code_2(self): ffi = cffi.FFI() ffi.set_source("package_name_1.mymod", None) py.test.raises(IOError, ffi.emit_python_code, 'unexisting/xyz.py')
def test_abi_emit_python_code_3(self): ffi = cffi.FFI() ffi.set_source("package_name_1.mymod", None) ffi.emit_python_code(str(self.udir.join('xyt.py'))) self.check_produced_files({'xyt.py': None})
def test_abi_compile_1(self): ffi = cffi.FFI() ffi.set_source("mod_name_in_package.mymod", None) x = ffi.compile() self.check_produced_files({'mod_name_in_package': {'mymod.py': None}}) assert x == os.path.join('.', 'mod_name_in_package', 'mymod.py')
def test_abi_compile_2(self): ffi = cffi.FFI() ffi.set_source("mod_name_in_package.mymod", None) x = ffi.compile('build2') self.check_produced_files({'build2': { 'mod_name_in_package': {'mymod.py': None}}}) assert x == os.path.join('build2', 'mod_name_in_package', 'mymod.py')
def test_abi_compile_3(self): ffi = cffi.FFI() ffi.set_source("mod_name_in_package.mymod", None) tmpdir = str(self.udir.join('build3')) x = ffi.compile(tmpdir) self.check_produced_files({'build3': { 'mod_name_in_package': {'mymod.py': None}}}) assert x == os.path.join(tmpdir, 'mod_name_in_package', 'mymod.py')