1edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepimport unittest, sys 2edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepfrom ctypes import * 4edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepimport _ctypes_test 5edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 6edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepctype_types = [c_byte, c_ubyte, c_short, c_ushort, c_int, c_uint, 7edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep c_long, c_ulong, c_longlong, c_ulonglong, c_double, c_float] 8edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoeppython_types = [int, int, int, int, int, long, 9edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep int, long, long, long, float, float] 10edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 11edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepclass PointersTestCase(unittest.TestCase): 12edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 13edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_pointer_crash(self): 14edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 15edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep class A(POINTER(c_ulong)): 16edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep pass 17edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 18edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep POINTER(c_ulong)(c_ulong(22)) 19edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # Pointer can't set contents: has no _type_ 20edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.assertRaises(TypeError, A, c_ulong(33)) 21edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 22edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_pass_pointers(self): 23edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep dll = CDLL(_ctypes_test.__file__) 24edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep func = dll._testfunc_p_p 25edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep func.restype = c_long 26edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 27edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep i = c_int(12345678) 28edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep## func.argtypes = (POINTER(c_int),) 29edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep address = func(byref(i)) 30edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.assertEqual(c_int.from_address(address).value, 12345678) 31edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 32edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep func.restype = POINTER(c_int) 33edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep res = func(pointer(i)) 34edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.assertEqual(res.contents.value, 12345678) 35edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.assertEqual(res[0], 12345678) 36edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 37edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_change_pointers(self): 38edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep dll = CDLL(_ctypes_test.__file__) 39edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep func = dll._testfunc_p_p 40edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 41edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep i = c_int(87654) 42edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep func.restype = POINTER(c_int) 43edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep func.argtypes = (POINTER(c_int),) 44edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 45edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep res = func(pointer(i)) 46edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.assertEqual(res[0], 87654) 47edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.assertEqual(res.contents.value, 87654) 48edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 49edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # C code: *res = 54345 50edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep res[0] = 54345 51edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.assertEqual(i.value, 54345) 52edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 53edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # C code: 54edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # int x = 12321; 55edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # res = &x 56edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep res.contents = c_int(12321) 57edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.assertEqual(i.value, 54345) 58edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 59edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_callbacks_with_pointers(self): 60edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # a function type receiving a pointer 61edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep PROTOTYPE = CFUNCTYPE(c_int, POINTER(c_int)) 62edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 63edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.result = [] 64edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 65edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def func(arg): 66edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep for i in range(10): 67edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep## print arg[i], 68edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.result.append(arg[i]) 69edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep## print 70edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return 0 71edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep callback = PROTOTYPE(func) 72edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 73edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep dll = CDLL(_ctypes_test.__file__) 74edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # This function expects a function pointer, 75edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # and calls this with an integer pointer as parameter. 76edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # The int pointer points to a table containing the numbers 1..10 77edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep doit = dll._testfunc_callback_with_pointer 78edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 79edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep## i = c_int(42) 80edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep## callback(byref(i)) 81edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep## self.assertTrue(i.value == 84) 82edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 83edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep doit(callback) 84edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep## print self.result 85edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep doit(callback) 86edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep## print self.result 87edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 88edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_basics(self): 89edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep from operator import delitem 90edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep for ct, pt in zip(ctype_types, python_types): 91edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep i = ct(42) 92edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep p = pointer(i) 93edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep## print type(p.contents), ct 94edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.assertTrue(type(p.contents) is ct) 95edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # p.contents is the same as p[0] 96edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep## print p.contents 97edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep## self.assertTrue(p.contents == 42) 98edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep## self.assertTrue(p[0] == 42) 99edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 100edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.assertRaises(TypeError, delitem, p, 0) 101edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 102edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_from_address(self): 103edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep from array import array 104edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep a = array('i', [100, 200, 300, 400, 500]) 105edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep addr = a.buffer_info()[0] 106edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 107edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep p = POINTER(POINTER(c_int)) 108edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep## print dir(p) 109edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep## print p.from_address 110edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep## print p.from_address(addr)[0][0] 111edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 112edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_other(self): 113edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep class Table(Structure): 114edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep _fields_ = [("a", c_int), 115edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep ("b", c_int), 116edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep ("c", c_int)] 117edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 118edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep pt = pointer(Table(1, 2, 3)) 119edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 120edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.assertEqual(pt.contents.a, 1) 121edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.assertEqual(pt.contents.b, 2) 122edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.assertEqual(pt.contents.c, 3) 123edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 124edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep pt.contents.c = 33 125edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 126edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep from ctypes import _pointer_type_cache 127edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep del _pointer_type_cache[Table] 128edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 129edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_basic(self): 130edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep p = pointer(c_int(42)) 131edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # Although a pointer can be indexed, it ha no length 132edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.assertRaises(TypeError, len, p) 133edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.assertEqual(p[0], 42) 134edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.assertEqual(p.contents.value, 42) 135edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 136edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_charpp(self): 137edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """Test that a character pointer-to-pointer is correctly passed""" 138edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep dll = CDLL(_ctypes_test.__file__) 139edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep func = dll._testfunc_c_p_p 140edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep func.restype = c_char_p 141edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep argv = (c_char_p * 2)() 142edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep argc = c_int( 2 ) 143edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep argv[0] = 'hello' 144edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep argv[1] = 'world' 145edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep result = func( byref(argc), argv ) 146edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep assert result == 'world', result 147edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 148edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_bug_1467852(self): 149edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # http://sourceforge.net/tracker/?func=detail&atid=532154&aid=1467852&group_id=71702 150edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep x = c_int(5) 151edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep dummy = [] 152edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep for i in range(32000): 153edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep dummy.append(c_int(i)) 154edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep y = c_int(6) 155edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep p = pointer(x) 156edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep pp = pointer(p) 157edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep q = pointer(y) 158edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep pp[0] = q # <== 159edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.assertEqual(p[0], 6) 160edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_c_void_p(self): 161edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # http://sourceforge.net/tracker/?func=detail&aid=1518190&group_id=5470&atid=105470 162edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if sizeof(c_void_p) == 4: 163edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.assertEqual(c_void_p(0xFFFFFFFFL).value, 164edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep c_void_p(-1).value) 165edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.assertEqual(c_void_p(0xFFFFFFFFFFFFFFFFL).value, 166edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep c_void_p(-1).value) 167edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep elif sizeof(c_void_p) == 8: 168edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.assertEqual(c_void_p(0xFFFFFFFFL).value, 169edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 0xFFFFFFFFL) 170edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.assertEqual(c_void_p(0xFFFFFFFFFFFFFFFFL).value, 171edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep c_void_p(-1).value) 172edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.assertEqual(c_void_p(0xFFFFFFFFFFFFFFFFFFFFFFFFL).value, 173edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep c_void_p(-1).value) 174edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 175edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.assertRaises(TypeError, c_void_p, 3.14) # make sure floats are NOT accepted 176edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.assertRaises(TypeError, c_void_p, object()) # nor other objects 177edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 178edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_pointers_bool(self): 179edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # NULL pointers have a boolean False value, non-NULL pointers True. 180edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.assertEqual(bool(POINTER(c_int)()), False) 181edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.assertEqual(bool(pointer(c_int())), True) 182edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 183edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.assertEqual(bool(CFUNCTYPE(None)(0)), False) 184edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.assertEqual(bool(CFUNCTYPE(None)(42)), True) 185edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 186edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # COM methods are boolean True: 187edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if sys.platform == "win32": 188edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep mth = WINFUNCTYPE(None)(42, "name", (), None) 189edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.assertEqual(bool(mth), True) 190edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 191edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepif __name__ == '__main__': 192edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep unittest.main() 193