test_pointers.py revision e8d09e581816aa7fdb812801c79e8f6bc55dc134
1babddfca758abe34ff12023f63b18d745fae7ca9Thomas Hellerimport unittest 2babddfca758abe34ff12023f63b18d745fae7ca9Thomas Heller 3babddfca758abe34ff12023f63b18d745fae7ca9Thomas Hellerfrom ctypes import * 4babddfca758abe34ff12023f63b18d745fae7ca9Thomas Hellerimport _ctypes_test 5babddfca758abe34ff12023f63b18d745fae7ca9Thomas Heller 6babddfca758abe34ff12023f63b18d745fae7ca9Thomas Hellerctype_types = [c_byte, c_ubyte, c_short, c_ushort, c_int, c_uint, 7babddfca758abe34ff12023f63b18d745fae7ca9Thomas Heller c_long, c_ulong, c_longlong, c_ulonglong, c_double, c_float] 8babddfca758abe34ff12023f63b18d745fae7ca9Thomas Hellerpython_types = [int, int, int, int, int, long, 9babddfca758abe34ff12023f63b18d745fae7ca9Thomas Heller int, long, long, long, float, float] 10babddfca758abe34ff12023f63b18d745fae7ca9Thomas Heller 11babddfca758abe34ff12023f63b18d745fae7ca9Thomas Hellerclass PointersTestCase(unittest.TestCase): 12babddfca758abe34ff12023f63b18d745fae7ca9Thomas Heller 13babddfca758abe34ff12023f63b18d745fae7ca9Thomas Heller def test_pointer_crash(self): 14e8d09e581816aa7fdb812801c79e8f6bc55dc134Tim Peters 15babddfca758abe34ff12023f63b18d745fae7ca9Thomas Heller class A(POINTER(c_ulong)): 16babddfca758abe34ff12023f63b18d745fae7ca9Thomas Heller pass 17babddfca758abe34ff12023f63b18d745fae7ca9Thomas Heller 18babddfca758abe34ff12023f63b18d745fae7ca9Thomas Heller POINTER(c_ulong)(c_ulong(22)) 19babddfca758abe34ff12023f63b18d745fae7ca9Thomas Heller # Pointer can't set contents: has no _type_ 20babddfca758abe34ff12023f63b18d745fae7ca9Thomas Heller self.failUnlessRaises(TypeError, A, c_ulong(33)) 21babddfca758abe34ff12023f63b18d745fae7ca9Thomas Heller 22babddfca758abe34ff12023f63b18d745fae7ca9Thomas Heller def test_pass_pointers(self): 23babddfca758abe34ff12023f63b18d745fae7ca9Thomas Heller dll = cdll.load(_ctypes_test.__file__) 24babddfca758abe34ff12023f63b18d745fae7ca9Thomas Heller func = dll._testfunc_p_p 25babddfca758abe34ff12023f63b18d745fae7ca9Thomas Heller func.restype = c_long 26babddfca758abe34ff12023f63b18d745fae7ca9Thomas Heller 27babddfca758abe34ff12023f63b18d745fae7ca9Thomas Heller i = c_int(12345678) 28babddfca758abe34ff12023f63b18d745fae7ca9Thomas Heller## func.argtypes = (POINTER(c_int),) 29babddfca758abe34ff12023f63b18d745fae7ca9Thomas Heller address = func(byref(i)) 30babddfca758abe34ff12023f63b18d745fae7ca9Thomas Heller self.failUnlessEqual(c_int.from_address(address).value, 12345678) 31babddfca758abe34ff12023f63b18d745fae7ca9Thomas Heller 32babddfca758abe34ff12023f63b18d745fae7ca9Thomas Heller func.restype = POINTER(c_int) 33babddfca758abe34ff12023f63b18d745fae7ca9Thomas Heller res = func(pointer(i)) 34babddfca758abe34ff12023f63b18d745fae7ca9Thomas Heller self.failUnlessEqual(res.contents.value, 12345678) 35babddfca758abe34ff12023f63b18d745fae7ca9Thomas Heller self.failUnlessEqual(res[0], 12345678) 36babddfca758abe34ff12023f63b18d745fae7ca9Thomas Heller 37babddfca758abe34ff12023f63b18d745fae7ca9Thomas Heller def test_change_pointers(self): 38babddfca758abe34ff12023f63b18d745fae7ca9Thomas Heller dll = cdll.load(_ctypes_test.__file__) 39babddfca758abe34ff12023f63b18d745fae7ca9Thomas Heller func = dll._testfunc_p_p 40babddfca758abe34ff12023f63b18d745fae7ca9Thomas Heller 41babddfca758abe34ff12023f63b18d745fae7ca9Thomas Heller i = c_int(87654) 42babddfca758abe34ff12023f63b18d745fae7ca9Thomas Heller func.restype = POINTER(c_int) 43babddfca758abe34ff12023f63b18d745fae7ca9Thomas Heller func.argtypes = (POINTER(c_int),) 44babddfca758abe34ff12023f63b18d745fae7ca9Thomas Heller 45babddfca758abe34ff12023f63b18d745fae7ca9Thomas Heller res = func(pointer(i)) 46babddfca758abe34ff12023f63b18d745fae7ca9Thomas Heller self.failUnlessEqual(res[0], 87654) 47babddfca758abe34ff12023f63b18d745fae7ca9Thomas Heller self.failUnlessEqual(res.contents.value, 87654) 48babddfca758abe34ff12023f63b18d745fae7ca9Thomas Heller 49babddfca758abe34ff12023f63b18d745fae7ca9Thomas Heller # C code: *res = 54345 50babddfca758abe34ff12023f63b18d745fae7ca9Thomas Heller res[0] = 54345 51babddfca758abe34ff12023f63b18d745fae7ca9Thomas Heller self.failUnlessEqual(i.value, 54345) 52babddfca758abe34ff12023f63b18d745fae7ca9Thomas Heller 53babddfca758abe34ff12023f63b18d745fae7ca9Thomas Heller # C code: 54babddfca758abe34ff12023f63b18d745fae7ca9Thomas Heller # int x = 12321; 55babddfca758abe34ff12023f63b18d745fae7ca9Thomas Heller # res = &x 56babddfca758abe34ff12023f63b18d745fae7ca9Thomas Heller res.contents = c_int(12321) 57babddfca758abe34ff12023f63b18d745fae7ca9Thomas Heller self.failUnlessEqual(i.value, 54345) 58babddfca758abe34ff12023f63b18d745fae7ca9Thomas Heller 59babddfca758abe34ff12023f63b18d745fae7ca9Thomas Heller def test_callbacks_with_pointers(self): 60babddfca758abe34ff12023f63b18d745fae7ca9Thomas Heller # a function type receiving a pointer 61babddfca758abe34ff12023f63b18d745fae7ca9Thomas Heller PROTOTYPE = CFUNCTYPE(c_int, POINTER(c_int)) 62babddfca758abe34ff12023f63b18d745fae7ca9Thomas Heller 63babddfca758abe34ff12023f63b18d745fae7ca9Thomas Heller self.result = [] 64babddfca758abe34ff12023f63b18d745fae7ca9Thomas Heller 65babddfca758abe34ff12023f63b18d745fae7ca9Thomas Heller def func(arg): 66babddfca758abe34ff12023f63b18d745fae7ca9Thomas Heller for i in range(10): 67babddfca758abe34ff12023f63b18d745fae7ca9Thomas Heller## print arg[i], 68babddfca758abe34ff12023f63b18d745fae7ca9Thomas Heller self.result.append(arg[i]) 69babddfca758abe34ff12023f63b18d745fae7ca9Thomas Heller## print 70babddfca758abe34ff12023f63b18d745fae7ca9Thomas Heller return 0 71babddfca758abe34ff12023f63b18d745fae7ca9Thomas Heller callback = PROTOTYPE(func) 72babddfca758abe34ff12023f63b18d745fae7ca9Thomas Heller 73babddfca758abe34ff12023f63b18d745fae7ca9Thomas Heller dll = cdll.load(_ctypes_test.__file__) 74babddfca758abe34ff12023f63b18d745fae7ca9Thomas Heller # This function expects a function pointer, 75babddfca758abe34ff12023f63b18d745fae7ca9Thomas Heller # and calls this with an integer pointer as parameter. 76babddfca758abe34ff12023f63b18d745fae7ca9Thomas Heller # The int pointer points to a table containing the numbers 1..10 77babddfca758abe34ff12023f63b18d745fae7ca9Thomas Heller doit = dll._testfunc_callback_with_pointer 78babddfca758abe34ff12023f63b18d745fae7ca9Thomas Heller 79babddfca758abe34ff12023f63b18d745fae7ca9Thomas Heller## i = c_int(42) 80babddfca758abe34ff12023f63b18d745fae7ca9Thomas Heller## callback(byref(i)) 81babddfca758abe34ff12023f63b18d745fae7ca9Thomas Heller## self.failUnless(i.value == 84) 82babddfca758abe34ff12023f63b18d745fae7ca9Thomas Heller 83babddfca758abe34ff12023f63b18d745fae7ca9Thomas Heller doit(callback) 84babddfca758abe34ff12023f63b18d745fae7ca9Thomas Heller## print self.result 85babddfca758abe34ff12023f63b18d745fae7ca9Thomas Heller doit(callback) 86babddfca758abe34ff12023f63b18d745fae7ca9Thomas Heller## print self.result 87e8d09e581816aa7fdb812801c79e8f6bc55dc134Tim Peters 88babddfca758abe34ff12023f63b18d745fae7ca9Thomas Heller def test_basics(self): 89babddfca758abe34ff12023f63b18d745fae7ca9Thomas Heller from operator import delitem 90babddfca758abe34ff12023f63b18d745fae7ca9Thomas Heller for ct, pt in zip(ctype_types, python_types): 91babddfca758abe34ff12023f63b18d745fae7ca9Thomas Heller i = ct(42) 92babddfca758abe34ff12023f63b18d745fae7ca9Thomas Heller p = pointer(i) 93babddfca758abe34ff12023f63b18d745fae7ca9Thomas Heller## print type(p.contents), ct 94babddfca758abe34ff12023f63b18d745fae7ca9Thomas Heller self.failUnless(type(p.contents) is ct) 95babddfca758abe34ff12023f63b18d745fae7ca9Thomas Heller # p.contents is the same as p[0] 96babddfca758abe34ff12023f63b18d745fae7ca9Thomas Heller## print p.contents 97babddfca758abe34ff12023f63b18d745fae7ca9Thomas Heller## self.failUnless(p.contents == 42) 98babddfca758abe34ff12023f63b18d745fae7ca9Thomas Heller## self.failUnless(p[0] == 42) 99babddfca758abe34ff12023f63b18d745fae7ca9Thomas Heller 100babddfca758abe34ff12023f63b18d745fae7ca9Thomas Heller self.assertRaises(TypeError, delitem, p, 0) 101babddfca758abe34ff12023f63b18d745fae7ca9Thomas Heller 102babddfca758abe34ff12023f63b18d745fae7ca9Thomas Heller def test_from_address(self): 103babddfca758abe34ff12023f63b18d745fae7ca9Thomas Heller from array import array 104babddfca758abe34ff12023f63b18d745fae7ca9Thomas Heller a = array('i', [100, 200, 300, 400, 500]) 105babddfca758abe34ff12023f63b18d745fae7ca9Thomas Heller addr = a.buffer_info()[0] 106babddfca758abe34ff12023f63b18d745fae7ca9Thomas Heller 107babddfca758abe34ff12023f63b18d745fae7ca9Thomas Heller p = POINTER(POINTER(c_int)) 108babddfca758abe34ff12023f63b18d745fae7ca9Thomas Heller## print dir(p) 109babddfca758abe34ff12023f63b18d745fae7ca9Thomas Heller## print p.from_address 110babddfca758abe34ff12023f63b18d745fae7ca9Thomas Heller## print p.from_address(addr)[0][0] 111babddfca758abe34ff12023f63b18d745fae7ca9Thomas Heller 112babddfca758abe34ff12023f63b18d745fae7ca9Thomas Heller def test_other(self): 113babddfca758abe34ff12023f63b18d745fae7ca9Thomas Heller class Table(Structure): 114babddfca758abe34ff12023f63b18d745fae7ca9Thomas Heller _fields_ = [("a", c_int), 115babddfca758abe34ff12023f63b18d745fae7ca9Thomas Heller ("b", c_int), 116babddfca758abe34ff12023f63b18d745fae7ca9Thomas Heller ("c", c_int)] 117babddfca758abe34ff12023f63b18d745fae7ca9Thomas Heller 118babddfca758abe34ff12023f63b18d745fae7ca9Thomas Heller pt = pointer(Table(1, 2, 3)) 119babddfca758abe34ff12023f63b18d745fae7ca9Thomas Heller 120babddfca758abe34ff12023f63b18d745fae7ca9Thomas Heller self.failUnlessEqual(pt.contents.a, 1) 121babddfca758abe34ff12023f63b18d745fae7ca9Thomas Heller self.failUnlessEqual(pt.contents.b, 2) 122babddfca758abe34ff12023f63b18d745fae7ca9Thomas Heller self.failUnlessEqual(pt.contents.c, 3) 123babddfca758abe34ff12023f63b18d745fae7ca9Thomas Heller 124babddfca758abe34ff12023f63b18d745fae7ca9Thomas Heller pt.contents.c = 33 125babddfca758abe34ff12023f63b18d745fae7ca9Thomas Heller 126babddfca758abe34ff12023f63b18d745fae7ca9Thomas Heller from ctypes import _pointer_type_cache 127babddfca758abe34ff12023f63b18d745fae7ca9Thomas Heller del _pointer_type_cache[Table] 128babddfca758abe34ff12023f63b18d745fae7ca9Thomas Heller 129babddfca758abe34ff12023f63b18d745fae7ca9Thomas Heller def test_basic(self): 130babddfca758abe34ff12023f63b18d745fae7ca9Thomas Heller p = pointer(c_int(42)) 131babddfca758abe34ff12023f63b18d745fae7ca9Thomas Heller # Although a pointer can be indexed, it ha no length 132babddfca758abe34ff12023f63b18d745fae7ca9Thomas Heller self.assertRaises(TypeError, len, p) 133babddfca758abe34ff12023f63b18d745fae7ca9Thomas Heller self.failUnlessEqual(p[0], 42) 134babddfca758abe34ff12023f63b18d745fae7ca9Thomas Heller self.failUnlessEqual(p.contents.value, 42) 135e8d09e581816aa7fdb812801c79e8f6bc55dc134Tim Peters 136babddfca758abe34ff12023f63b18d745fae7ca9Thomas Heller def test_incomplete(self): 137babddfca758abe34ff12023f63b18d745fae7ca9Thomas Heller lpcell = POINTER("cell") 138babddfca758abe34ff12023f63b18d745fae7ca9Thomas Heller class cell(Structure): 139babddfca758abe34ff12023f63b18d745fae7ca9Thomas Heller _fields_ = [("value", c_int), 140babddfca758abe34ff12023f63b18d745fae7ca9Thomas Heller ("next", lpcell)] 141babddfca758abe34ff12023f63b18d745fae7ca9Thomas Heller SetPointerType(lpcell, cell) 142babddfca758abe34ff12023f63b18d745fae7ca9Thomas Heller 143babddfca758abe34ff12023f63b18d745fae7ca9Thomas Heller # Make a structure containing a pointer to itself: 144babddfca758abe34ff12023f63b18d745fae7ca9Thomas Heller c = cell() 145babddfca758abe34ff12023f63b18d745fae7ca9Thomas Heller c.value = 42 146babddfca758abe34ff12023f63b18d745fae7ca9Thomas Heller c.next = pointer(c) 147babddfca758abe34ff12023f63b18d745fae7ca9Thomas Heller 148babddfca758abe34ff12023f63b18d745fae7ca9Thomas Heller result = [] 149babddfca758abe34ff12023f63b18d745fae7ca9Thomas Heller for i in range(8): 150babddfca758abe34ff12023f63b18d745fae7ca9Thomas Heller result.append(c.value) 151babddfca758abe34ff12023f63b18d745fae7ca9Thomas Heller c = c.next[0] 152babddfca758abe34ff12023f63b18d745fae7ca9Thomas Heller self.failUnlessEqual(result, [42] * 8) 153babddfca758abe34ff12023f63b18d745fae7ca9Thomas Heller 154babddfca758abe34ff12023f63b18d745fae7ca9Thomas Heller from ctypes import _pointer_type_cache 155babddfca758abe34ff12023f63b18d745fae7ca9Thomas Heller del _pointer_type_cache[cell] 156babddfca758abe34ff12023f63b18d745fae7ca9Thomas Heller 157babddfca758abe34ff12023f63b18d745fae7ca9Thomas Heller def test_charpp( self ): 158babddfca758abe34ff12023f63b18d745fae7ca9Thomas Heller """Test that a character pointer-to-pointer is correctly passed""" 159babddfca758abe34ff12023f63b18d745fae7ca9Thomas Heller dll = cdll.load(_ctypes_test.__file__) 160babddfca758abe34ff12023f63b18d745fae7ca9Thomas Heller func = dll._testfunc_c_p_p 161babddfca758abe34ff12023f63b18d745fae7ca9Thomas Heller func.restype = c_char_p 162babddfca758abe34ff12023f63b18d745fae7ca9Thomas Heller argv = (c_char_p * 2)() 163babddfca758abe34ff12023f63b18d745fae7ca9Thomas Heller argc = c_int( 2 ) 164babddfca758abe34ff12023f63b18d745fae7ca9Thomas Heller argv[0] = 'hello' 165babddfca758abe34ff12023f63b18d745fae7ca9Thomas Heller argv[1] = 'world' 166babddfca758abe34ff12023f63b18d745fae7ca9Thomas Heller result = func( byref(argc), argv ) 167babddfca758abe34ff12023f63b18d745fae7ca9Thomas Heller assert result == 'world', result 168babddfca758abe34ff12023f63b18d745fae7ca9Thomas Heller 169e8d09e581816aa7fdb812801c79e8f6bc55dc134Tim Peters 170babddfca758abe34ff12023f63b18d745fae7ca9Thomas Hellerif __name__ == '__main__': 171babddfca758abe34ff12023f63b18d745fae7ca9Thomas Heller unittest.main() 172