~ubuntu-branches/ubuntu/maverick/python3.1/maverick

« back to all changes in this revision

Viewing changes to Lib/ctypes/test/test_funcptr.py

  • Committer: Bazaar Package Importer
  • Author(s): Matthias Klose
  • Date: 2009-03-23 00:01:27 UTC
  • Revision ID: james.westby@ubuntu.com-20090323000127-5fstfxju4ufrhthq
Tags: upstream-3.1~a1+20090322
ImportĀ upstreamĀ versionĀ 3.1~a1+20090322

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
import os, unittest
 
2
from ctypes import *
 
3
 
 
4
try:
 
5
    WINFUNCTYPE
 
6
except NameError:
 
7
    # fake to enable this test on Linux
 
8
    WINFUNCTYPE = CFUNCTYPE
 
9
 
 
10
import _ctypes_test
 
11
lib = CDLL(_ctypes_test.__file__)
 
12
 
 
13
class CFuncPtrTestCase(unittest.TestCase):
 
14
    def test_basic(self):
 
15
        X = WINFUNCTYPE(c_int, c_int, c_int)
 
16
 
 
17
        def func(*args):
 
18
            return len(args)
 
19
 
 
20
        x = X(func)
 
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))
 
25
 
 
26
    def test_first(self):
 
27
        StdCallback = WINFUNCTYPE(c_int, c_int, c_int)
 
28
        CdeclCallback = CFUNCTYPE(c_int, c_int, c_int)
 
29
 
 
30
        def func(a, b):
 
31
            return a + b
 
32
 
 
33
        s = StdCallback(func)
 
34
        c = CdeclCallback(func)
 
35
 
 
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)
 
44
 
 
45
    def test_structures(self):
 
46
        WNDPROC = WINFUNCTYPE(c_long, c_int, c_int, c_int, c_int)
 
47
 
 
48
        def wndproc(hwnd, msg, wParam, lParam):
 
49
            return hwnd + msg + wParam + lParam
 
50
 
 
51
        HINSTANCE = c_int
 
52
        HICON = c_int
 
53
        HCURSOR = c_int
 
54
        LPCTSTR = c_char_p
 
55
 
 
56
        class WNDCLASS(Structure):
 
57
            _fields_ = [("style", c_uint),
 
58
                        ("lpfnWndProc", WNDPROC),
 
59
                        ("cbClsExtra", c_int),
 
60
                        ("cbWndExtra", c_int),
 
61
                        ("hInstance", HINSTANCE),
 
62
                        ("hIcon", HICON),
 
63
                        ("hCursor", HCURSOR),
 
64
                        ("lpszMenuName", LPCTSTR),
 
65
                        ("lpszClassName", LPCTSTR)]
 
66
 
 
67
        wndclass = WNDCLASS()
 
68
        wndclass.lpfnWndProc = WNDPROC(wndproc)
 
69
 
 
70
        WNDPROC_2 = WINFUNCTYPE(c_long, c_int, c_int, c_int, c_int)
 
71
 
 
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))
 
76
        # instead:
 
77
 
 
78
        self.failUnless(WNDPROC is WNDPROC_2)
 
79
        # 'wndclass.lpfnWndProc' leaks 94 references.  Why?
 
80
        self.failUnlessEqual(wndclass.lpfnWndProc(1, 2, 3, 4), 10)
 
81
 
 
82
 
 
83
        f = wndclass.lpfnWndProc
 
84
 
 
85
        del wndclass
 
86
        del wndproc
 
87
 
 
88
        self.failUnlessEqual(f(10, 11, 12, 13), 46)
 
89
 
 
90
    def test_dllfunctions(self):
 
91
 
 
92
        def NoNullHandle(value):
 
93
            if not value:
 
94
                raise WinError()
 
95
            return value
 
96
 
 
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)
 
102
 
 
103
 
 
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)
 
109
 
 
110
        def c_string(init):
 
111
            size = len(init) + 1
 
112
            return (c_char*size)(*init)
 
113
 
 
114
        s = "a\nb\nc"
 
115
        b = c_string(s)
 
116
 
 
117
##        b = (c_char * (len(s)+1))()
 
118
##        b.value = s
 
119
 
 
120
##        b = c_string(s)
 
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)
 
125
 
 
126
if __name__ == '__main__':
 
127
    unittest.main()