1 import unittest 2 from ctypes import * 3 4 import _ctypes_test 5 6 lib = CDLL(_ctypes_test.__file__) 7 8 class StringPtrTestCase(unittest.TestCase): 9 10 def test__POINTER_c_char(self): 11 class X(Structure): 12 _fields_ = [("str", POINTER(c_char))] 13 x = X() 14 15 # NULL pointer access 16 self.assertRaises(ValueError, getattr, x.str, "contents") 17 b = c_buffer("Hello, World") 18 from sys import getrefcount as grc 19 self.assertEqual(grc(b), 2) 20 x.str = b 21 self.assertEqual(grc(b), 3) 22 23 # POINTER(c_char) and Python string is NOT compatible 24 # POINTER(c_char) and c_buffer() is compatible 25 for i in range(len(b)): 26 self.assertEqual(b[i], x.str[i]) 27 28 self.assertRaises(TypeError, setattr, x, "str", "Hello, World") 29 30 def test__c_char_p(self): 31 class X(Structure): 32 _fields_ = [("str", c_char_p)] 33 x = X() 34 35 # c_char_p and Python string is compatible 36 # c_char_p and c_buffer is NOT compatible 37 self.assertEqual(x.str, None) 38 x.str = "Hello, World" 39 self.assertEqual(x.str, "Hello, World") 40 b = c_buffer("Hello, World") 41 self.assertRaises(TypeError, setattr, x, "str", b) 42 43 44 def test_functions(self): 45 strchr = lib.my_strchr 46 strchr.restype = c_char_p 47 48 # c_char_p and Python string is compatible 49 # c_char_p and c_buffer are now compatible 50 strchr.argtypes = c_char_p, c_char 51 self.assertEqual(strchr("abcdef", "c"), "cdef") 52 self.assertEqual(strchr(c_buffer("abcdef"), "c"), "cdef") 53 54 # POINTER(c_char) and Python string is NOT compatible 55 # POINTER(c_char) and c_buffer() is compatible 56 strchr.argtypes = POINTER(c_char), c_char 57 buf = c_buffer("abcdef") 58 self.assertEqual(strchr(buf, "c"), "cdef") 59 self.assertEqual(strchr("abcdef", "c"), "cdef") 60 61 # XXX These calls are dangerous, because the first argument 62 # to strchr is no longer valid after the function returns! 63 # So we must keep a reference to buf separately 64 65 strchr.restype = POINTER(c_char) 66 buf = c_buffer("abcdef") 67 r = strchr(buf, "c") 68 x = r[0], r[1], r[2], r[3], r[4] 69 self.assertEqual(x, ("c", "d", "e", "f", "\000")) 70 del buf 71 # x1 will NOT be the same as x, usually: 72 x1 = r[0], r[1], r[2], r[3], r[4] 73 74 if __name__ == '__main__': 75 unittest.main() 76