183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehimport os, unittest 283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehfrom ctypes import * 383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehtry: 583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh WINFUNCTYPE 683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehexcept NameError: 783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh # fake to enable this test on Linux 883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh WINFUNCTYPE = CFUNCTYPE 983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 1083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehimport _ctypes_test 1183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehlib = CDLL(_ctypes_test.__file__) 1283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 1383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehclass CFuncPtrTestCase(unittest.TestCase): 1483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh def test_basic(self): 1583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh X = WINFUNCTYPE(c_int, c_int, c_int) 1683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 1783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh def func(*args): 1883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh return len(args) 1983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 2083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh x = X(func) 2183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh self.assertEqual(x.restype, c_int) 2283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh self.assertEqual(x.argtypes, (c_int, c_int)) 2383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh self.assertEqual(sizeof(x), sizeof(c_voidp)) 2483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh self.assertEqual(sizeof(X), sizeof(c_voidp)) 2583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 2683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh def test_first(self): 2783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh StdCallback = WINFUNCTYPE(c_int, c_int, c_int) 2883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh CdeclCallback = CFUNCTYPE(c_int, c_int, c_int) 2983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 3083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh def func(a, b): 3183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh return a + b 3283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 3383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh s = StdCallback(func) 3483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh c = CdeclCallback(func) 3583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 3683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh self.assertEqual(s(1, 2), 3) 3783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh self.assertEqual(c(1, 2), 3) 3883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh # The following no longer raises a TypeError - it is now 3983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh # possible, as in C, to call cdecl functions with more parameters. 4083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh #self.assertRaises(TypeError, c, 1, 2, 3) 4183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh self.assertEqual(c(1, 2, 3, 4, 5, 6), 3) 4283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh if not WINFUNCTYPE is CFUNCTYPE and os.name != "ce": 4383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh self.assertRaises(TypeError, s, 1, 2, 3) 4483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 4583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh def test_structures(self): 4683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh WNDPROC = WINFUNCTYPE(c_long, c_int, c_int, c_int, c_int) 4783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 4883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh def wndproc(hwnd, msg, wParam, lParam): 4983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh return hwnd + msg + wParam + lParam 5083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 5183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh HINSTANCE = c_int 5283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh HICON = c_int 5383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh HCURSOR = c_int 5483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh LPCTSTR = c_char_p 5583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 5683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh class WNDCLASS(Structure): 5783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh _fields_ = [("style", c_uint), 5883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh ("lpfnWndProc", WNDPROC), 5983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh ("cbClsExtra", c_int), 6083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh ("cbWndExtra", c_int), 6183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh ("hInstance", HINSTANCE), 6283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh ("hIcon", HICON), 6383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh ("hCursor", HCURSOR), 6483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh ("lpszMenuName", LPCTSTR), 6583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh ("lpszClassName", LPCTSTR)] 6683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 6783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh wndclass = WNDCLASS() 6883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh wndclass.lpfnWndProc = WNDPROC(wndproc) 6983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 7083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh WNDPROC_2 = WINFUNCTYPE(c_long, c_int, c_int, c_int, c_int) 7183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 7283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh # This is no longer true, now that WINFUNCTYPE caches created types internally. 7383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh ## # CFuncPtr subclasses are compared by identity, so this raises a TypeError: 7483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh ## self.assertRaises(TypeError, setattr, wndclass, 7583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh ## "lpfnWndProc", WNDPROC_2(wndproc)) 7683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh # instead: 7783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 7883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh self.assertTrue(WNDPROC is WNDPROC_2) 7983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh # 'wndclass.lpfnWndProc' leaks 94 references. Why? 8083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh self.assertEqual(wndclass.lpfnWndProc(1, 2, 3, 4), 10) 8183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 8283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 8383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh f = wndclass.lpfnWndProc 8483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 8583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh del wndclass 8683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh del wndproc 8783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 8883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh self.assertEqual(f(10, 11, 12, 13), 46) 8983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 9083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh def test_dllfunctions(self): 9183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 9283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh def NoNullHandle(value): 9383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh if not value: 9483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh raise WinError() 9583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh return value 9683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 9783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh strchr = lib.my_strchr 9883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh strchr.restype = c_char_p 9983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh strchr.argtypes = (c_char_p, c_char) 10083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh self.assertEqual(strchr("abcdefghi", "b"), "bcdefghi") 10183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh self.assertEqual(strchr("abcdefghi", "x"), None) 10283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 10383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 10483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh strtok = lib.my_strtok 10583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh strtok.restype = c_char_p 10683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh # Neither of this does work: strtok changes the buffer it is passed 10783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh## strtok.argtypes = (c_char_p, c_char_p) 10883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh## strtok.argtypes = (c_string, c_char_p) 10983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 11083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh def c_string(init): 11183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh size = len(init) + 1 11283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh return (c_char*size)(*init) 11383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 11483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh s = "a\nb\nc" 11583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh b = c_string(s) 11683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 11783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh## b = (c_char * (len(s)+1))() 11883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh## b.value = s 11983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 12083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh## b = c_string(s) 12183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh self.assertEqual(strtok(b, "\n"), "a") 12283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh self.assertEqual(strtok(None, "\n"), "b") 12383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh self.assertEqual(strtok(None, "\n"), "c") 12483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh self.assertEqual(strtok(None, "\n"), None) 12583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 12683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehif __name__ == '__main__': 12783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh unittest.main() 128