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