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