1from ctypes import *
2import sys, unittest
3import os
4from ctypes.util import find_library
5from ctypes.test import is_resource_enabled
6
7libc_name = None
8if os.name == "nt":
9    libc_name = find_library("c")
10elif os.name == "ce":
11    libc_name = "coredll"
12elif sys.platform == "cygwin":
13    libc_name = "cygwin1.dll"
14else:
15    libc_name = find_library("c")
16
17if is_resource_enabled("printing"):
18    print "libc_name is", libc_name
19
20class LoaderTest(unittest.TestCase):
21
22    unknowndll = "xxrandomnamexx"
23
24    if libc_name is not None:
25        def test_load(self):
26            CDLL(libc_name)
27            CDLL(os.path.basename(libc_name))
28            self.assertRaises(OSError, CDLL, self.unknowndll)
29
30    if libc_name is not None and os.path.basename(libc_name) == "libc.so.6":
31        def test_load_version(self):
32            cdll.LoadLibrary("libc.so.6")
33            # linux uses version, libc 9 should not exist
34            self.assertRaises(OSError, cdll.LoadLibrary, "libc.so.9")
35            self.assertRaises(OSError, cdll.LoadLibrary, self.unknowndll)
36
37    def test_find(self):
38        for name in ("c", "m"):
39            lib = find_library(name)
40            if lib:
41                cdll.LoadLibrary(lib)
42                CDLL(lib)
43
44    if os.name in ("nt", "ce"):
45        def test_load_library(self):
46            self.assertFalse(libc_name is None)
47            if is_resource_enabled("printing"):
48                print find_library("kernel32")
49                print find_library("user32")
50
51            if os.name == "nt":
52                windll.kernel32.GetModuleHandleW
53                windll["kernel32"].GetModuleHandleW
54                windll.LoadLibrary("kernel32").GetModuleHandleW
55                WinDLL("kernel32").GetModuleHandleW
56            elif os.name == "ce":
57                windll.coredll.GetModuleHandleW
58                windll["coredll"].GetModuleHandleW
59                windll.LoadLibrary("coredll").GetModuleHandleW
60                WinDLL("coredll").GetModuleHandleW
61
62        def test_load_ordinal_functions(self):
63            import _ctypes_test
64            dll = WinDLL(_ctypes_test.__file__)
65            # We load the same function both via ordinal and name
66            func_ord = dll[2]
67            func_name = dll.GetString
68            # addressof gets the address where the function pointer is stored
69            a_ord = addressof(func_ord)
70            a_name = addressof(func_name)
71            f_ord_addr = c_void_p.from_address(a_ord).value
72            f_name_addr = c_void_p.from_address(a_name).value
73            self.assertEqual(hex(f_ord_addr), hex(f_name_addr))
74
75            self.assertRaises(AttributeError, dll.__getitem__, 1234)
76
77    if os.name == "nt":
78        def test_1703286_A(self):
79            from _ctypes import LoadLibrary, FreeLibrary
80            # On winXP 64-bit, advapi32 loads at an address that does
81            # NOT fit into a 32-bit integer.  FreeLibrary must be able
82            # to accept this address.
83
84            # These are tests for http://www.python.org/sf/1703286
85            handle = LoadLibrary("advapi32")
86            FreeLibrary(handle)
87
88        def test_1703286_B(self):
89            # Since on winXP 64-bit advapi32 loads like described
90            # above, the (arbitrarily selected) CloseEventLog function
91            # also has a high address.  'call_function' should accept
92            # addresses so large.
93            from _ctypes import call_function
94            advapi32 = windll.advapi32
95            # Calling CloseEventLog with a NULL argument should fail,
96            # but the call should not segfault or so.
97            self.assertEqual(0, advapi32.CloseEventLog(None))
98            windll.kernel32.GetProcAddress.argtypes = c_void_p, c_char_p
99            windll.kernel32.GetProcAddress.restype = c_void_p
100            proc = windll.kernel32.GetProcAddress(advapi32._handle, "CloseEventLog")
101            self.assertTrue(proc)
102            # This is the real test: call the function via 'call_function'
103            self.assertEqual(0, call_function(proc, (None,)))
104
105if __name__ == "__main__":
106    unittest.main()
107