7
# fake to enable this test on Linux
8
WINFUNCTYPE = CFUNCTYPE
11
lib = CDLL(_ctypes_test.__file__)
13
class CFuncPtrTestCase(unittest.TestCase):
15
X = WINFUNCTYPE(c_int, c_int, c_int)
21
self.failUnlessEqual(x.restype, c_int)
22
self.failUnlessEqual(x.argtypes, (c_int, c_int))
23
self.failUnlessEqual(sizeof(x), sizeof(c_voidp))
24
self.failUnlessEqual(sizeof(X), sizeof(c_voidp))
27
StdCallback = WINFUNCTYPE(c_int, c_int, c_int)
28
CdeclCallback = CFUNCTYPE(c_int, c_int, c_int)
34
c = CdeclCallback(func)
36
self.failUnlessEqual(s(1, 2), 3)
37
self.failUnlessEqual(c(1, 2), 3)
38
# The following no longer raises a TypeError - it is now
39
# possible, as in C, to call cdecl functions with more parameters.
40
#self.assertRaises(TypeError, c, 1, 2, 3)
41
self.failUnlessEqual(c(1, 2, 3, 4, 5, 6), 3)
42
if not WINFUNCTYPE is CFUNCTYPE and os.name != "ce":
43
self.assertRaises(TypeError, s, 1, 2, 3)
45
def test_structures(self):
46
WNDPROC = WINFUNCTYPE(c_long, c_int, c_int, c_int, c_int)
48
def wndproc(hwnd, msg, wParam, lParam):
49
return hwnd + msg + wParam + lParam
56
class WNDCLASS(Structure):
57
_fields_ = [("style", c_uint),
58
("lpfnWndProc", WNDPROC),
59
("cbClsExtra", c_int),
60
("cbWndExtra", c_int),
61
("hInstance", HINSTANCE),
64
("lpszMenuName", LPCTSTR),
65
("lpszClassName", LPCTSTR)]
68
wndclass.lpfnWndProc = WNDPROC(wndproc)
70
WNDPROC_2 = WINFUNCTYPE(c_long, c_int, c_int, c_int, c_int)
72
# This is no longer true, now that WINFUNCTYPE caches created types internally.
73
## # CFuncPtr subclasses are compared by identity, so this raises a TypeError:
74
## self.assertRaises(TypeError, setattr, wndclass,
75
## "lpfnWndProc", WNDPROC_2(wndproc))
78
self.failUnless(WNDPROC is WNDPROC_2)
79
# 'wndclass.lpfnWndProc' leaks 94 references. Why?
80
self.failUnlessEqual(wndclass.lpfnWndProc(1, 2, 3, 4), 10)
83
f = wndclass.lpfnWndProc
88
self.failUnlessEqual(f(10, 11, 12, 13), 46)
90
def test_dllfunctions(self):
92
def NoNullHandle(value):
97
strchr = lib.my_strchr
98
strchr.restype = c_char_p
99
strchr.argtypes = (c_char_p, c_char)
100
self.failUnlessEqual(strchr("abcdefghi", "b"), "bcdefghi")
101
self.failUnlessEqual(strchr("abcdefghi", "x"), None)
104
strtok = lib.my_strtok
105
strtok.restype = c_char_p
106
# Neither of this does work: strtok changes the buffer it is passed
107
## strtok.argtypes = (c_char_p, c_char_p)
108
## strtok.argtypes = (c_string, c_char_p)
112
return (c_char*size)(*init)
117
## b = (c_char * (len(s)+1))()
121
self.failUnlessEqual(strtok(b, b"\n"), "a")
122
self.failUnlessEqual(strtok(None, b"\n"), "b")
123
self.failUnlessEqual(strtok(None, b"\n"), "c")
124
self.failUnlessEqual(strtok(None, b"\n"), None)
126
if __name__ == '__main__':