1 import unittest, sys 2 3 from ctypes import * 4 import _ctypes_test 5 6 ctype_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] 8 python_types = [int, int, int, int, int, long, 9 int, long, long, long, float, float] 10 11 class 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 res.contents = c_int(12321) 57 self.assertEqual(i.value, 54345) 58 59 def test_callbacks_with_pointers(self): 60 # a function type receiving a pointer 61 PROTOTYPE = CFUNCTYPE(c_int, POINTER(c_int)) 62 63 self.result = [] 64 65 def func(arg): 66 for i in range(10): 67 ## print arg[i], 68 self.result.append(arg[i]) 69 ## print 70 return 0 71 callback = PROTOTYPE(func) 72 73 dll = CDLL(_ctypes_test.__file__) 74 # This function expects a function pointer, 75 # and calls this with an integer pointer as parameter. 76 # The int pointer points to a table containing the numbers 1..10 77 doit = dll._testfunc_callback_with_pointer 78 79 ## i = c_int(42) 80 ## callback(byref(i)) 81 ## self.assertTrue(i.value == 84) 82 83 doit(callback) 84 ## print self.result 85 doit(callback) 86 ## print self.result 87 88 def test_basics(self): 89 from operator import delitem 90 for ct, pt in zip(ctype_types, python_types): 91 i = ct(42) 92 p = pointer(i) 93 ## print type(p.contents), ct 94 self.assertTrue(type(p.contents) is ct) 95 # p.contents is the same as p[0] 96 ## print p.contents 97 ## self.assertTrue(p.contents == 42) 98 ## self.assertTrue(p[0] == 42) 99 100 self.assertRaises(TypeError, delitem, p, 0) 101 102 def test_from_address(self): 103 from array import array 104 a = array('i', [100, 200, 300, 400, 500]) 105 addr = a.buffer_info()[0] 106 107 p = POINTER(POINTER(c_int)) 108 ## print dir(p) 109 ## print p.from_address 110 ## print p.from_address(addr)[0][0] 111 112 def test_other(self): 113 class Table(Structure): 114 _fields_ = [("a", c_int), 115 ("b", c_int), 116 ("c", c_int)] 117 118 pt = pointer(Table(1, 2, 3)) 119 120 self.assertEqual(pt.contents.a, 1) 121 self.assertEqual(pt.contents.b, 2) 122 self.assertEqual(pt.contents.c, 3) 123 124 pt.contents.c = 33 125 126 from ctypes import _pointer_type_cache 127 del _pointer_type_cache[Table] 128 129 def test_basic(self): 130 p = pointer(c_int(42)) 131 # Although a pointer can be indexed, it ha no length 132 self.assertRaises(TypeError, len, p) 133 self.assertEqual(p[0], 42) 134 self.assertEqual(p.contents.value, 42) 135 136 def test_charpp(self): 137 """Test that a character pointer-to-pointer is correctly passed""" 138 dll = CDLL(_ctypes_test.__file__) 139 func = dll._testfunc_c_p_p 140 func.restype = c_char_p 141 argv = (c_char_p * 2)() 142 argc = c_int( 2 ) 143 argv[0] = 'hello' 144 argv[1] = 'world' 145 result = func( byref(argc), argv ) 146 assert result == 'world', result 147 148 def test_bug_1467852(self): 149 # http://sourceforge.net/tracker/?func=detail&atid=532154&aid=1467852&group_id=71702 150 x = c_int(5) 151 dummy = [] 152 for i in range(32000): 153 dummy.append(c_int(i)) 154 y = c_int(6) 155 p = pointer(x) 156 pp = pointer(p) 157 q = pointer(y) 158 pp[0] = q # <== 159 self.assertEqual(p[0], 6) 160 def test_c_void_p(self): 161 # http://sourceforge.net/tracker/?func=detail&aid=1518190&group_id=5470&atid=105470 162 if sizeof(c_void_p) == 4: 163 self.assertEqual(c_void_p(0xFFFFFFFFL).value, 164 c_void_p(-1).value) 165 self.assertEqual(c_void_p(0xFFFFFFFFFFFFFFFFL).value, 166 c_void_p(-1).value) 167 elif sizeof(c_void_p) == 8: 168 self.assertEqual(c_void_p(0xFFFFFFFFL).value, 169 0xFFFFFFFFL) 170 self.assertEqual(c_void_p(0xFFFFFFFFFFFFFFFFL).value, 171 c_void_p(-1).value) 172 self.assertEqual(c_void_p(0xFFFFFFFFFFFFFFFFFFFFFFFFL).value, 173 c_void_p(-1).value) 174 175 self.assertRaises(TypeError, c_void_p, 3.14) # make sure floats are NOT accepted 176 self.assertRaises(TypeError, c_void_p, object()) # nor other objects 177 178 def test_pointers_bool(self): 179 # NULL pointers have a boolean False value, non-NULL pointers True. 180 self.assertEqual(bool(POINTER(c_int)()), False) 181 self.assertEqual(bool(pointer(c_int())), True) 182 183 self.assertEqual(bool(CFUNCTYPE(None)(0)), False) 184 self.assertEqual(bool(CFUNCTYPE(None)(42)), True) 185 186 # COM methods are boolean True: 187 if sys.platform == "win32": 188 mth = WINFUNCTYPE(None)(42, "name", (), None) 189 self.assertEqual(bool(mth), True) 190 191 if __name__ == '__main__': 192 unittest.main() 193