def test__StructDescr(self): from _ffi import _StructDescr, Field, types longsize = types.slong.sizeof() fields = [ Field('x', types.slong), Field('y', types.slong), ] descr = _StructDescr('foo', fields) assert descr.ffitype.sizeof() == longsize * 2 assert descr.ffitype.name == 'struct foo'
def test_alignment(self): from _ffi import _StructDescr, Field, types longsize = types.slong.sizeof() fields = [ Field('x', types.sbyte), Field('y', types.slong), ] descr = _StructDescr('foo', fields) assert descr.ffitype.sizeof() == longsize * 2 assert fields[0].offset == 0 assert fields[1].offset == longsize # aligned to WORD
def test_missing_field(self): from _ffi import _StructDescr, Field, types longsize = types.slong.sizeof() fields = [ Field('x', types.slong), Field('y', types.slong), ] descr = _StructDescr('foo', fields) struct = descr.allocate() raises(AttributeError, "struct.getfield('missing')") raises(AttributeError, "struct.setfield('missing', 42)")
def test_getfield_setfield(self): from _ffi import _StructDescr, Field, types longsize = types.slong.sizeof() fields = [ Field('x', types.slong), Field('y', types.slong), ] descr = _StructDescr('foo', fields) struct = descr.allocate() struct.setfield('x', 42) struct.setfield('y', 43) assert struct.getfield('x') == 42 assert struct.getfield('y') == 43 mem = self.read_raw_mem(struct.getaddr(), 'c_long', 2) assert mem == [42, 43]
def test_pointer_to_incomplete_struct(self): from _ffi import _StructDescr, Field, types longsize = types.slong.sizeof() fields = [ Field('x', types.slong), Field('y', types.slong), ] descr = _StructDescr('foo') foo_ffitype = descr.ffitype foo_p = types.Pointer(descr.ffitype) assert foo_p.deref_pointer() is foo_ffitype descr.define_fields(fields) assert descr.ffitype is foo_ffitype assert foo_p.deref_pointer() is foo_ffitype assert types.Pointer(descr.ffitype) is foo_p
def test_getfield_setfield_longlong(self): import sys from _ffi import _StructDescr, Field, types longsize = types.slong.sizeof() fields = [ Field('slonglong', types.slonglong), Field('ulonglong', types.ulonglong), ] descr = _StructDescr('foo', fields) struct = descr.allocate() struct.setfield('slonglong', 9223372036854775808) assert struct.getfield('slonglong') == -9223372036854775808 struct.setfield('ulonglong', -1) assert struct.getfield('ulonglong') == 18446744073709551615 mem = self.read_raw_mem(struct.getaddr(), 'c_longlong', 2) assert mem == [-9223372036854775808, -1]
def test_define_fields(self): from _ffi import _StructDescr, Field, types longsize = types.slong.sizeof() fields = [ Field('x', types.slong), Field('y', types.slong), ] descr = _StructDescr('foo') assert descr.ffitype.name == 'struct foo' assert repr(descr.ffitype) == '<ffi type struct foo (incomplete)>' raises(ValueError, "descr.ffitype.sizeof()") raises(ValueError, "descr.allocate()") # descr.define_fields(fields) assert repr(descr.ffitype) == '<ffi type struct foo>' assert descr.ffitype.sizeof() == longsize * 2 raises(ValueError, "descr.define_fields(fields)")
def test_getfield_setfield_unsigned_types(self): import sys from _ffi import _StructDescr, Field, types longsize = types.slong.sizeof() fields = [ Field('ubyte', types.ubyte), Field('ushort', types.ushort), Field('uint', types.uint), Field('ulong', types.ulong), Field('char', types.char), Field('unichar', types.unichar), Field('ptr', types.void_p), ] descr = _StructDescr('foo', fields) struct = descr.allocate() struct.setfield('ubyte', -1) assert struct.getfield('ubyte') == 255 struct.setfield('ushort', -1) assert struct.getfield('ushort') == 65535 struct.setfield('uint', 43) assert struct.getfield('uint') == 43 struct.setfield('ulong', -1) assert struct.getfield('ulong') == sys.maxint * 2 + 1 struct.setfield('ulong', sys.maxint * 2 + 2) assert struct.getfield('ulong') == 0 struct.setfield('char', 'a') assert struct.getfield('char') == 'a' struct.setfield('unichar', u'\u1234') assert struct.getfield('unichar') == u'\u1234' struct.setfield('ptr', -1) assert struct.getfield('ptr') == sys.maxint * 2 + 1
def test_unknown_type(self): if self.runappdirect: skip('cannot use self.dummy_type with -A') from _ffi import _StructDescr, Field fields = [ Field('x', self.dummy_type), ] descr = _StructDescr('foo', fields) struct = descr.allocate() raises(TypeError, "struct.getfield('x')") raises(TypeError, "struct.setfield('x', 42)")
def test_byval_result(self): """ DLLEXPORT struct Point make_point(long x, long y) { struct Point p; p.x = x; p.y = y; return p; } """ from _ffi import CDLL, types, _StructDescr, Field Point = _StructDescr('Point', [ Field('x', types.slong), Field('y', types.slong), ]) libfoo = CDLL(self.libfoo_name) make_point = libfoo.getfunc('make_point', [types.slong, types.slong], Point.ffitype) # p = make_point(12, 34) assert p.getfield('x') == 12 assert p.getfield('y') == 34
def test_getfield_setfield_signed_types(self): import sys from _ffi import _StructDescr, Field, types longsize = types.slong.sizeof() fields = [ Field('sbyte', types.sbyte), Field('sshort', types.sshort), Field('sint', types.sint), Field('slong', types.slong), ] descr = _StructDescr('foo', fields) struct = descr.allocate() struct.setfield('sbyte', 128) assert struct.getfield('sbyte') == -128 struct.setfield('sshort', 32768) assert struct.getfield('sshort') == -32768 struct.setfield('sint', 43) assert struct.getfield('sint') == 43 struct.setfield('slong', sys.maxint + 1) assert struct.getfield('slong') == -sys.maxint - 1 struct.setfield('slong', sys.maxint * 3) assert struct.getfield('slong') == sys.maxint - 2
def test_getfield_setfield_float(self): import sys from _ffi import _StructDescr, Field, types longsize = types.slong.sizeof() fields = [ Field('x', types.double), ] descr = _StructDescr('foo', fields) struct = descr.allocate() struct.setfield('x', 123.4) assert struct.getfield('x') == 123.4 mem = self.read_raw_mem(struct.getaddr(), 'c_double', 1) assert mem == [123.4]
def main(): from _ffi import _StructDescr, Field, types fields = [ Field('x', types.slong), ] descr = _StructDescr('foo', fields) struct = descr.allocate() i = 0 while i < 300: x = struct.getfield('x') # ID: getfield x = x+1 struct.setfield('x', x) # ID: setfield i += 1 return struct.getfield('x')
def test_byval_argument(self): """ struct Point { long x; long y; }; DLLEXPORT long sum_point(struct Point p) { return p.x + p.y; } """ from _ffi import CDLL, types, _StructDescr, Field Point = _StructDescr('Point', [ Field('x', types.slong), Field('y', types.slong), ]) libfoo = CDLL(self.libfoo_name) sum_point = libfoo.getfunc('sum_point', [Point.ffitype], types.slong) # p = Point.allocate() p.setfield('x', 30) p.setfield('y', 12) res = sum_point(p) assert res == 42
def test_nested_structure(self): from _ffi import _StructDescr, Field, types longsize = types.slong.sizeof() foo_fields = [ Field('x', types.slong), Field('y', types.slong), ] foo_descr = _StructDescr('foo', foo_fields) # bar_fields = [ Field('x', types.slong), Field('foo', foo_descr.ffitype), ] bar_descr = _StructDescr('bar', bar_fields) assert bar_descr.ffitype.sizeof() == longsize * 3 # struct = bar_descr.allocate() struct.setfield('x', 40) # reading a nested structure yields a reference to it struct_foo = struct.getfield('foo') struct_foo.setfield('x', 41) struct_foo.setfield('y', 42) mem = self.read_raw_mem(struct.getaddr(), 'c_long', 3) assert mem == [40, 41, 42] # struct_foo2 = foo_descr.allocate() struct_foo2.setfield('x', 141) struct_foo2.setfield('y', 142) # writing a nested structure copies its memory into the target struct.setfield('foo', struct_foo2) struct_foo2.setfield('x', 241) struct_foo2.setfield('y', 242) mem = self.read_raw_mem(struct.getaddr(), 'c_long', 3) assert mem == [40, 141, 142] mem = self.read_raw_mem(struct_foo2.getaddr(), 'c_long', 2) assert mem == [241, 242]
def test_getfield_setfield_singlefloat(self): import sys from _ffi import _StructDescr, Field, types longsize = types.slong.sizeof() fields = [ Field('x', types.float), ] descr = _StructDescr('foo', fields) struct = descr.allocate() struct.setfield('x', 123.4) # this is a value which DOES loose # precision in a single float assert 0 < abs(struct.getfield('x') - 123.4) < 0.0001 # struct.setfield('x', 123.5) # this is a value which does not loose # precision in a single float assert struct.getfield('x') == 123.5 mem = self.read_raw_mem(struct.getaddr(), 'c_float', 1) assert mem == [123.5]
class Point(Structure): _fields_ = [ Field('x', types.slong), Field('y', types.slong), ]