def test_functionptr_simple(self): ffi = FFI(backend=self.Backend()) py.test.raises(TypeError, ffi.callback, "int(*)(int)") py.test.raises(TypeError, ffi.callback, "int(*)(int)", 0) def cb(n): return n + 1 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) == "<cdata 'int(*)(int)'>" res = q(45) assert res == 46
def test_cast_pointer_and_int(self): ffi = FFI(backend=self.Backend()) a = ffi.new("short int[]", [0x1234, 0x5678]) l1 = ffi.cast("intptr_t", a) p = ffi.cast("short*", a) l2 = ffi.cast("intptr_t", p) assert int(l1) == int(l2) != 0 q = ffi.cast("short*", l1) assert q == ffi.cast("short*", int(l1)) assert q[0] == 0x1234
def test_cast_pointer_and_int(self): ffi = FFI(backend=self.Backend()) a = ffi.new("short int[]", [0x1234, 0x5678]) l1 = ffi.cast("intptr_t", a) p = ffi.cast("short*", a) l2 = ffi.cast("intptr_t", p) assert int(l1) == int(l2) != 0 q = ffi.cast("short*", l1) assert q == ffi.cast("short*", int(l1)) assert q[0] == 0x1234
def test_cast_between_pointers(self): ffi = FFI(backend=self.Backend()) a = ffi.new("short int[]", [0x1234, 0x5678]) p = ffi.cast("short*", a) p2 = ffi.cast("int*", p) q = ffi.cast("char*", p2) data = ''.join([q[i] for i in range(4)]) if sys.byteorder == 'little': assert data == '\x34\x12\x78\x56' else: assert data == '\x12\x34\x56\x78'
def test_cast_functionptr_and_int(self): ffi = FFI(backend=self.Backend()) def cb(n): return n + 1 a = ffi.callback("int(*)(int)", cb) p = ffi.cast("void *", a) assert p b = ffi.cast("int(*)(int)", p) assert b(41) == 42 assert a == b assert hash(a) == hash(b)
def test_new_pointer_to_array(self): ffi = FFI(backend=self.Backend()) a = ffi.new("int[4]", [100, 102, 104, 106]) p = ffi.new("int *", a) assert p[0] == ffi.cast("int *", a) assert p[0][2] == 104 p = ffi.cast("int *", a) assert p[0] == 100 assert p[1] == 102 assert p[2] == 104 assert p[3] == 106
def test_new_pointer_to_array(self): ffi = FFI(backend=self.Backend()) a = ffi.new("int[4]", [100, 102, 104, 106]) p = ffi.new("int *", a) assert p[0] == ffi.cast("int *", a) assert p[0][2] == 104 p = ffi.cast("int *", a) assert p[0] == 100 assert p[1] == 102 assert p[2] == 104 assert p[3] == 106
def test_cast_between_pointers(self): ffi = FFI(backend=self.Backend()) a = ffi.new("short int[]", [0x1234, 0x5678]) p = ffi.cast("short*", a) p2 = ffi.cast("int*", p) q = ffi.cast("char*", p2) data = ''.join([q[i] for i in range(4)]) if sys.byteorder == 'little': assert data == '\x34\x12\x78\x56' else: assert data == '\x12\x34\x56\x78'
def test_enum_non_contiguous(self): ffi = FFI(backend=self.Backend()) ffi.cdef("enum foo { A, B=42, C };") assert int(ffi.cast("enum foo", "A")) == 0 assert int(ffi.cast("enum foo", "B")) == 42 assert int(ffi.cast("enum foo", "C")) == 43 assert str(ffi.cast("enum foo", 0)) == "A" assert str(ffi.cast("enum foo", 42)) == "B" assert str(ffi.cast("enum foo", 43)) == "C" invalid_value = ffi.cast("enum foo", 2) assert int(invalid_value) == 2 assert str(invalid_value) == "#2"
def test_enum_non_contiguous(self): ffi = FFI(backend=self.Backend()) ffi.cdef("enum foo { A, B=42, C };") assert int(ffi.cast("enum foo", "A")) == 0 assert int(ffi.cast("enum foo", "B")) == 42 assert int(ffi.cast("enum foo", "C")) == 43 assert str(ffi.cast("enum foo", 0)) == "A" assert str(ffi.cast("enum foo", 42)) == "B" assert str(ffi.cast("enum foo", 43)) == "C" invalid_value = ffi.cast("enum foo", 2) assert int(invalid_value) == 2 assert str(invalid_value) == "#2"
def test_pointer_direct(self): ffi = FFI(backend=self.Backend()) p = ffi.cast("int*", 0) assert bool(p) is False assert p == ffi.cast("int*", 0) a = ffi.new("int[]", [123, 456]) p = ffi.cast("int*", a) assert bool(p) is True assert p == ffi.cast("int*", a) assert p != ffi.cast("int*", 0) assert p[0] == 123 assert p[1] == 456
def test_pointer_direct(self): ffi = FFI(backend=self.Backend()) p = ffi.cast("int*", 0) assert bool(p) is False assert p == ffi.cast("int*", 0) a = ffi.new("int[]", [123, 456]) p = ffi.cast("int*", a) assert bool(p) is True assert p == ffi.cast("int*", a) assert p != ffi.cast("int*", 0) assert p[0] == 123 assert p[1] == 456
def test_cast_functionptr_and_int(self): ffi = FFI(backend=self.Backend()) def cb(n): return n + 1 a = ffi.callback("int(*)(int)", cb) p = ffi.cast("void *", a) assert p b = ffi.cast("int(*)(int)", p) assert b(41) == 42 assert a == b assert hash(a) == hash(b)
def test_string_from_char_array(self): ffi = FFI(backend=self.Backend()) assert str(ffi.cast("char", "x")) == "x" p = ffi.new("char[]", "hello.") p[5] = '!' assert str(p) == "hello!" p[6] = '?' assert str(p) == "hello!?" p[3] = '\x00' assert str(p) == "hel" py.test.raises(IndexError, "p[7] = 'X'") # a = ffi.new("char[]", "hello\x00world") assert len(a) == 12 p = ffi.cast("char *", a) assert str(p) == 'hello'
def test_char(self): ffi = FFI(backend=self.Backend()) assert ffi.new("char", "\xff")[0] == '\xff' assert ffi.new("char")[0] == '\x00' assert int(ffi.cast("char", 300)) == 300 - 256 assert bool(ffi.new("char")) py.test.raises(TypeError, ffi.new, "char", 32) py.test.raises(TypeError, ffi.new, "char", "foo") # p = ffi.new("char[]", ['a', 'b', '\x9c']) assert len(p) == 3 assert p[0] == 'a' assert p[1] == 'b' assert p[2] == '\x9c' p[0] = '\xff' assert p[0] == '\xff' p = ffi.new("char[]", "abcd") assert len(p) == 5 assert p[4] == '\x00' # like in C, with: char[] p = "abcd"; # p = ffi.new("char[4]", "ab") assert len(p) == 4 assert [p[i] for i in range(4)] == ['a', 'b', '\x00', '\x00'] p = ffi.new("char[2]", "ab") assert len(p) == 2 assert [p[i] for i in range(2)] == ['a', 'b'] py.test.raises(IndexError, ffi.new, "char[2]", "abc")
def test_char(self): ffi = FFI(backend=self.Backend()) assert ffi.new("char", "\xff")[0] == '\xff' assert ffi.new("char")[0] == '\x00' assert int(ffi.cast("char", 300)) == 300 - 256 assert bool(ffi.new("char")) py.test.raises(TypeError, ffi.new, "char", 32) py.test.raises(TypeError, ffi.new, "char", "foo") # p = ffi.new("char[]", ['a', 'b', '\x9c']) assert len(p) == 3 assert p[0] == 'a' assert p[1] == 'b' assert p[2] == '\x9c' p[0] = '\xff' assert p[0] == '\xff' p = ffi.new("char[]", "abcd") assert len(p) == 5 assert p[4] == '\x00' # like in C, with: char[] p = "abcd"; # p = ffi.new("char[4]", "ab") assert len(p) == 4 assert [p[i] for i in range(4)] == ['a', 'b', '\x00', '\x00'] p = ffi.new("char[2]", "ab") assert len(p) == 2 assert [p[i] for i in range(2)] == ['a', 'b'] py.test.raises(IndexError, ffi.new, "char[2]", "abc")
def test_string_from_char_array(self): ffi = FFI(backend=self.Backend()) assert str(ffi.cast("char", "x")) == "x" p = ffi.new("char[]", "hello.") p[5] = '!' assert str(p) == "hello!" p[6] = '?' assert str(p) == "hello!?" p[3] = '\x00' assert str(p) == "hel" py.test.raises(IndexError, "p[7] = 'X'") # a = ffi.new("char[]", "hello\x00world") assert len(a) == 12 p = ffi.cast("char *", a) assert str(p) == 'hello'
def test_function_pointer(self): ffi = FFI(backend=self.Backend()) def cb(charp): assert repr(charp) == "<cdata 'char *'>" return 42 fptr = ffi.callback("int(*)(const char *txt)", cb) assert fptr != ffi.callback("int(*)(const char *)", cb) assert repr(fptr) == "<cdata 'int(*)(char *)' calling %r>" % (cb, ) res = fptr("Hello") assert res == 42 # ffi.cdef(""" int puts(const char *); int fflush(void *); """) fptr = ffi.cast("int(*)(const char *txt)", ffi.C.puts) assert fptr == ffi.C.puts assert repr(fptr) == "<cdata 'int(*)(char *)'>" with FdWriteCapture() as fd: fptr("world") ffi.C.fflush(None) res = fd.getvalue() assert res == 'world\n'
def test_sizeof_cdata(self): ffi = FFI(backend=self.Backend()) assert ffi.sizeof(ffi.new("short")) == SIZE_OF_PTR assert ffi.sizeof(ffi.cast("short", 123)) == SIZE_OF_SHORT # a = ffi.new("int[]", [10, 11, 12, 13, 14]) assert len(a) == 5 assert ffi.sizeof(a) == 5 * SIZE_OF_INT
def test_sizeof_cdata(self): ffi = FFI(backend=self.Backend()) assert ffi.sizeof(ffi.new("short")) == SIZE_OF_PTR assert ffi.sizeof(ffi.cast("short", 123)) == SIZE_OF_SHORT # a = ffi.new("int[]", [10, 11, 12, 13, 14]) assert len(a) == 5 assert ffi.sizeof(a) == 5 * SIZE_OF_INT
def test_ffi_string(self): ffi = FFI(backend=self.Backend()) a = ffi.new("int[]", range(100, 110)) s = ffi.string(ffi.cast("void *", a), 8) assert type(s) is str if sys.byteorder == 'little': assert s == '\x64\x00\x00\x00\x65\x00\x00\x00' else: assert s == '\x00\x00\x00\x64\x00\x00\x00\x65'
def test_ffi_string(self): ffi = FFI(backend=self.Backend()) a = ffi.new("int[]", range(100, 110)) s = ffi.string(ffi.cast("void *", a), 8) assert type(s) is str if sys.byteorder == 'little': assert s == '\x64\x00\x00\x00\x65\x00\x00\x00' else: assert s == '\x00\x00\x00\x64\x00\x00\x00\x65'
def test_cast_array_to_charp(self): ffi = FFI(backend=self.Backend()) a = ffi.new("short int[]", [0x1234, 0x5678]) p = ffi.cast("char*", a) data = ''.join([p[i] for i in range(4)]) if sys.byteorder == 'little': assert data == '\x34\x12\x78\x56' else: assert data == '\x12\x34\x56\x78'
def test_cast_array_to_charp(self): ffi = FFI(backend=self.Backend()) a = ffi.new("short int[]", [0x1234, 0x5678]) p = ffi.cast("char*", a) data = ''.join([p[i] for i in range(4)]) if sys.byteorder == 'little': assert data == '\x34\x12\x78\x56' else: assert data == '\x12\x34\x56\x78'
def test_pointer_arithmetic(self): ffi = FFI(backend=self.Backend()) s = ffi.new("short[]", range(100, 110)) p = ffi.cast("short *", s) assert p[2] == 102 assert p+1 == p+1 assert p+1 != p+0 assert p == p+0 == p-0 assert (p+1)[0] == 101 assert (p+19)[-10] == 109 assert (p+5) - (p+1) == 4 assert p == s+0 assert p+1 == s+1
def test_vararg(self): ffi = FFI(backend=self.Backend()) ffi.cdef(""" int printf(const char *format, ...); int fflush(void *); """) with FdWriteCapture() as fd: ffi.C.printf("hello with no arguments\n") ffi.C.printf("hello, %s!\n", ffi.new("char[]", "world")) ffi.C.printf(ffi.new("char[]", "hello, %s!\n"), ffi.new("char[]", "world2")) ffi.C.printf("hello int %d long %ld long long %lld\n", ffi.cast("int", 42), ffi.cast("long", 84), ffi.cast("long long", 168)) ffi.C.printf("hello %p\n", None) ffi.C.fflush(None) res = fd.getvalue() assert res == ("hello with no arguments\n" "hello, world!\n" "hello, world2!\n" "hello int 42 long 84 long long 168\n" "hello (nil)\n")
def test_pointer_arithmetic(self): ffi = FFI(backend=self.Backend()) s = ffi.new("short[]", range(100, 110)) p = ffi.cast("short *", s) assert p[2] == 102 assert p + 1 == p + 1 assert p + 1 != p + 0 assert p == p + 0 == p - 0 assert (p + 1)[0] == 101 assert (p + 19)[-10] == 109 assert (p + 5) - (p + 1) == 4 assert p == s + 0 assert p + 1 == s + 1
def test_vararg(self): ffi = FFI(backend=self.Backend()) ffi.cdef(""" int printf(const char *format, ...); int fflush(void *); """) with FdWriteCapture() as fd: ffi.C.printf("hello with no arguments\n") ffi.C.printf("hello, %s!\n", ffi.new("char[]", "world")) ffi.C.printf(ffi.new("char[]", "hello, %s!\n"), ffi.new("char[]", "world2")) ffi.C.printf("hello int %d long %ld long long %lld\n", ffi.cast("int", 42), ffi.cast("long", 84), ffi.cast("long long", 168)) ffi.C.printf("hello %p\n", None) ffi.C.fflush(None) res = fd.getvalue() assert res == ("hello with no arguments\n" "hello, world!\n" "hello, world2!\n" "hello int 42 long 84 long long 168\n" "hello (nil)\n")
def test_functionptr_simple(self): ffi = FFI(backend=self.Backend()) py.test.raises(TypeError, ffi.callback, "int(*)(int)") py.test.raises(TypeError, ffi.callback, "int(*)(int)", 0) def cb(n): return n + 1 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) == "<cdata 'int(*)(int)'>" res = q(45) assert res == 46
def test_char_cast(self): ffi = FFI(backend=self.Backend()) p = ffi.cast("int", '\x01') assert ffi.typeof(p) is ffi.typeof("int") assert int(p) == 1 p = ffi.cast("int", ffi.cast("char", "a")) assert int(p) == ord("a") p = ffi.cast("int", ffi.cast("char", "\x80")) assert int(p) == 0x80 # "char" is considered unsigned in this case p = ffi.cast("int", "\x81") assert int(p) == 0x81
def test_char_cast(self): ffi = FFI(backend=self.Backend()) p = ffi.cast("int", '\x01') assert ffi.typeof(p) is ffi.typeof("int") assert int(p) == 1 p = ffi.cast("int", ffi.cast("char", "a")) assert int(p) == ord("a") p = ffi.cast("int", ffi.cast("char", "\x80")) assert int(p) == 0x80 # "char" is considered unsigned in this case p = ffi.cast("int", "\x81") assert int(p) == 0x81
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 == "A" s.e = "D" assert s.e == "D" assert s[0].e == "D" s[0].e = "C" assert s.e == "C" assert s[0].e == "C" s.e = ffi.cast("enum foo", -1) assert s.e == '#-1' assert s[0].e == '#-1' s.e = s.e py.test.raises(TypeError, "s.e = None")
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 == "A" s.e = "D" assert s.e == "D" assert s[0].e == "D" s[0].e = "C" assert s.e == "C" assert s[0].e == "C" s.e = ffi.cast("enum foo", -1) assert s.e == '#-1' assert s[0].e == '#-1' s.e = s.e py.test.raises(TypeError, "s.e = None")
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_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_voidp(self): ffi = FFI(backend=self.Backend()) py.test.raises(TypeError, ffi.new, "void") p = ffi.new("void *") assert p[0] is None a = ffi.new("int[]", [10, 11, 12]) p = ffi.new("void *", a) vp = p[0] py.test.raises(TypeError, "vp[0]") py.test.raises(TypeError, ffi.new, "short *", a) # ffi.cdef("struct foo { void *p; int *q; short *r; };") s = ffi.new("struct foo") s.p = a # works s.q = a # works py.test.raises(TypeError, "s.r = a") # fails b = ffi.cast("int *", a) s.p = b # works s.q = b # works py.test.raises(TypeError, "s.r = b") # fails
def test_voidp(self): ffi = FFI(backend=self.Backend()) py.test.raises(TypeError, ffi.new, "void") p = ffi.new("void *") assert p[0] is None a = ffi.new("int[]", [10, 11, 12]) p = ffi.new("void *", a) vp = p[0] py.test.raises(TypeError, "vp[0]") py.test.raises(TypeError, ffi.new, "short *", a) # ffi.cdef("struct foo { void *p; int *q; short *r; };") s = ffi.new("struct foo") s.p = a # works s.q = a # works py.test.raises(TypeError, "s.r = a") # fails b = ffi.cast("int *", a) s.p = b # works s.q = b # works py.test.raises(TypeError, "s.r = b") # fails
def test_repr(self): typerepr = self.TypeRepr ffi = FFI(backend=self.Backend()) ffi.cdef("struct foo { short a, b, c; };") p = ffi.cast("unsigned short int", 0) assert repr(p) == "<cdata 'unsigned short'>" assert repr(ffi.typeof(p)) == typerepr % "unsigned short" p = ffi.cast("int*", 0) assert repr(p) == "<cdata 'int *'>" assert repr(ffi.typeof(p)) == typerepr % "int *" # p = ffi.new("int") assert repr(p) == "<cdata 'int *' owning %d bytes>" % SIZE_OF_INT assert repr(ffi.typeof(p)) == typerepr % "int *" p = ffi.new("int*") assert repr(p) == "<cdata 'int * *' owning %d bytes>" % SIZE_OF_PTR assert repr(ffi.typeof(p)) == typerepr % "int * *" p = ffi.new("int [2]") assert repr(p) == "<cdata 'int[2]' owning %d bytes>" % (2 * SIZE_OF_INT) assert repr(ffi.typeof(p)) == typerepr % "int[2]" p = ffi.new("int*[2][3]") assert repr( p) == "<cdata 'int *[2][3]' owning %d bytes>" % (6 * SIZE_OF_PTR) assert repr(ffi.typeof(p)) == typerepr % "int *[2][3]" p = ffi.new("struct foo") assert repr(p) == "<cdata 'struct foo *' owning %d bytes>" % ( 3 * SIZE_OF_SHORT) assert repr(ffi.typeof(p)) == typerepr % "struct foo *" # q = ffi.cast("short", -123) assert repr(q) == "<cdata 'short'>" assert repr(ffi.typeof(q)) == typerepr % "short" p = ffi.new("int") q = ffi.cast("short*", p) assert repr(q) == "<cdata 'short *'>" assert repr(ffi.typeof(q)) == typerepr % "short *" p = ffi.new("int [2]") q = ffi.cast("int*", p) assert repr(q) == "<cdata 'int *'>" assert repr(ffi.typeof(q)) == typerepr % "int *" p = ffi.new("struct foo") q = ffi.cast("struct foo *", p) assert repr(q) == "<cdata 'struct foo *'>" assert repr(ffi.typeof(q)) == typerepr % "struct foo *" q = q[0] assert repr(q) == "<cdata 'struct foo'>" assert repr(ffi.typeof(q)) == typerepr % "struct foo"
def test_repr(self): typerepr = self.TypeRepr ffi = FFI(backend=self.Backend()) ffi.cdef("struct foo { short a, b, c; };") p = ffi.cast("unsigned short int", 0) assert repr(p) == "<cdata 'unsigned short'>" assert repr(ffi.typeof(p)) == typerepr % "unsigned short" p = ffi.cast("int*", 0) assert repr(p) == "<cdata 'int *'>" assert repr(ffi.typeof(p)) == typerepr % "int *" # p = ffi.new("int") assert repr(p) == "<cdata 'int *' owning %d bytes>" % SIZE_OF_INT assert repr(ffi.typeof(p)) == typerepr % "int *" p = ffi.new("int*") assert repr(p) == "<cdata 'int * *' owning %d bytes>" % SIZE_OF_PTR assert repr(ffi.typeof(p)) == typerepr % "int * *" p = ffi.new("int [2]") assert repr(p) == "<cdata 'int[2]' owning %d bytes>" % (2*SIZE_OF_INT) assert repr(ffi.typeof(p)) == typerepr % "int[2]" p = ffi.new("int*[2][3]") assert repr(p) == "<cdata 'int *[2][3]' owning %d bytes>" % ( 6*SIZE_OF_PTR) assert repr(ffi.typeof(p)) == typerepr % "int *[2][3]" p = ffi.new("struct foo") assert repr(p) == "<cdata 'struct foo *' owning %d bytes>" % ( 3*SIZE_OF_SHORT) assert repr(ffi.typeof(p)) == typerepr % "struct foo *" # q = ffi.cast("short", -123) assert repr(q) == "<cdata 'short'>" assert repr(ffi.typeof(q)) == typerepr % "short" p = ffi.new("int") q = ffi.cast("short*", p) assert repr(q) == "<cdata 'short *'>" assert repr(ffi.typeof(q)) == typerepr % "short *" p = ffi.new("int [2]") q = ffi.cast("int*", p) assert repr(q) == "<cdata 'int *'>" assert repr(ffi.typeof(q)) == typerepr % "int *" p = ffi.new("struct foo") q = ffi.cast("struct foo *", p) assert repr(q) == "<cdata 'struct foo *'>" assert repr(ffi.typeof(q)) == typerepr % "struct foo *" q = q[0] assert repr(q) == "<cdata 'struct foo'>" assert repr(ffi.typeof(q)) == typerepr % "struct foo"
def test_function_pointer(self): ffi = FFI(backend=self.Backend()) def cb(charp): assert repr(charp) == "<cdata 'char *'>" return 42 fptr = ffi.callback("int(*)(const char *txt)", cb) assert fptr != ffi.callback("int(*)(const char *)", cb) assert repr(fptr) == "<cdata 'int(*)(char *)' calling %r>" % (cb,) res = fptr("Hello") assert res == 42 # ffi.cdef(""" int puts(const char *); int fflush(void *); """) fptr = ffi.cast("int(*)(const char *txt)", ffi.C.puts) assert fptr == ffi.C.puts assert repr(fptr) == "<cdata 'int(*)(char *)'>" with FdWriteCapture() as fd: fptr("world") ffi.C.fflush(None) res = fd.getvalue() assert res == 'world\n'
def test_enum(self): ffi = FFI(backend=self.Backend()) ffi.cdef("enum foo { A, B, CC, D };") assert int(ffi.cast("enum foo", "A")) == 0 assert int(ffi.cast("enum foo", "B")) == 1 assert int(ffi.cast("enum foo", "CC")) == 2 assert int(ffi.cast("enum foo", "D")) == 3 ffi.cdef("enum bar { A, B=-2, CC, D };") assert int(ffi.cast("enum bar", "A")) == 0 assert int(ffi.cast("enum bar", "B")) == -2 assert int(ffi.cast("enum bar", "CC")) == -1 assert int(ffi.cast("enum bar", "D")) == 0 assert ffi.cast("enum bar", "B") != ffi.cast("enum bar", "B") assert ffi.cast("enum foo", "A") != ffi.cast("enum bar", "A") assert ffi.cast("enum bar", "A") != ffi.cast("int", 0) assert repr(ffi.cast("enum bar", "CC")) == "<cdata 'enum bar'>"
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", "A") assert float(a) == ord("A") a = ffi.cast("int", 12.9) assert int(a) == 12 a = ffi.cast("char", 66.9 + 256) assert str(a) == "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", "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 str(a) == "B"
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", "A") assert float(a) == ord("A") a = ffi.cast("int", 12.9) assert int(a) == 12 a = ffi.cast("char", 66.9 + 256) assert str(a) == "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", "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 str(a) == "B"
def test_enum(self): ffi = FFI(backend=self.Backend()) ffi.cdef("enum foo { A, B, CC, D };") assert int(ffi.cast("enum foo", "A")) == 0 assert int(ffi.cast("enum foo", "B")) == 1 assert int(ffi.cast("enum foo", "CC")) == 2 assert int(ffi.cast("enum foo", "D")) == 3 ffi.cdef("enum bar { A, B=-2, CC, D };") assert int(ffi.cast("enum bar", "A")) == 0 assert int(ffi.cast("enum bar", "B")) == -2 assert int(ffi.cast("enum bar", "CC")) == -1 assert int(ffi.cast("enum bar", "D")) == 0 assert ffi.cast("enum bar", "B") != ffi.cast("enum bar", "B") assert ffi.cast("enum foo", "A") != ffi.cast("enum bar", "A") assert ffi.cast("enum bar", "A") != ffi.cast("int", 0) assert repr(ffi.cast("enum bar", "CC")) == "<cdata 'enum bar'>"