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