@@ -108,7 +108,7 @@ class CFunctionType(_CFuncPtr):
108108 return CFunctionType
109109
110110if _os .name == "nt" :
111- from _ctypes import LoadLibrary as _dlopen
111+ from _ctypes import LoadLibrary as _LoadLibrary
112112 from _ctypes import FUNCFLAG_STDCALL as _FUNCFLAG_STDCALL
113113
114114 _win_functype_cache = {}
@@ -416,52 +416,59 @@ def __init__(self, name, mode=DEFAULT_MODE, handle=None,
416416 use_errno = False ,
417417 use_last_error = False ,
418418 winmode = None ):
419+ class _FuncPtr (_CFuncPtr ):
420+ _flags_ = self ._func_flags_
421+ _restype_ = self ._func_restype_
422+ if use_errno :
423+ _flags_ |= _FUNCFLAG_USE_ERRNO
424+ if use_last_error :
425+ _flags_ |= _FUNCFLAG_USE_LASTERROR
426+
427+ self ._FuncPtr = _FuncPtr
419428 if name :
420429 name = _os .fspath (name )
421430
431+ self ._handle = self ._load_library (name , mode , handle , winmode )
432+
433+ if _os .name == "nt" :
434+ def _load_library (self , name , mode , handle , winmode ):
435+ if winmode is None :
436+ import nt as _nt
437+ winmode = _nt ._LOAD_LIBRARY_SEARCH_DEFAULT_DIRS
438+ # WINAPI LoadLibrary searches for a DLL if the given name
439+ # is not fully qualified with an explicit drive. For POSIX
440+ # compatibility, and because the DLL search path no longer
441+ # contains the working directory, begin by fully resolving
442+ # any name that contains a path separator.
443+ if name is not None and ('/' in name or '\\ ' in name ):
444+ name = _nt ._getfullpathname (name )
445+ winmode |= _nt ._LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR
446+ self ._name = name
447+ if handle is not None :
448+ return handle
449+ return _LoadLibrary (self ._name , winmode )
450+
451+ else :
452+ def _load_library (self , name , mode , handle , winmode ):
422453 # If the filename that has been provided is an iOS/tvOS/watchOS
423454 # .fwork file, dereference the location to the true origin of the
424455 # binary.
425- if name .endswith (".fwork" ):
456+ if name and name .endswith (".fwork" ):
426457 with open (name ) as f :
427458 name = _os .path .join (
428459 _os .path .dirname (_sys .executable ),
429460 f .read ().strip ()
430461 )
431-
432- self ._name = name
433- flags = self ._func_flags_
434- if use_errno :
435- flags |= _FUNCFLAG_USE_ERRNO
436- if use_last_error :
437- flags |= _FUNCFLAG_USE_LASTERROR
438- if _sys .platform .startswith ("aix" ):
439- """When the name contains ".a(" and ends with ")",
440- e.g., "libFOO.a(libFOO.so)" - this is taken to be an
441- archive(member) syntax for dlopen(), and the mode is adjusted.
442- Otherwise, name is presented to dlopen() as a file argument.
443- """
444- if name and name .endswith (")" ) and ".a(" in name :
445- mode |= ( _os .RTLD_MEMBER | _os .RTLD_NOW )
446- if _os .name == "nt" :
447- if winmode is not None :
448- mode = winmode
449- else :
450- import nt
451- mode = nt ._LOAD_LIBRARY_SEARCH_DEFAULT_DIRS
452- if '/' in name or '\\ ' in name :
453- self ._name = nt ._getfullpathname (self ._name )
454- mode |= nt ._LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR
455-
456- class _FuncPtr (_CFuncPtr ):
457- _flags_ = flags
458- _restype_ = self ._func_restype_
459- self ._FuncPtr = _FuncPtr
460-
461- if handle is None :
462- self ._handle = _dlopen (self ._name , mode )
463- else :
464- self ._handle = handle
462+ if _sys .platform .startswith ("aix" ):
463+ """When the name contains ".a(" and ends with ")",
464+ e.g., "libFOO.a(libFOO.so)" - this is taken to be an
465+ archive(member) syntax for dlopen(), and the mode is adjusted.
466+ Otherwise, name is presented to dlopen() as a file argument.
467+ """
468+ if name and name .endswith (")" ) and ".a(" in name :
469+ mode |= _os .RTLD_MEMBER | _os .RTLD_NOW
470+ self ._name = name
471+ return _dlopen (name , mode )
465472
466473 def __repr__ (self ):
467474 return "<%s '%s', handle %x at %#x>" % \
0 commit comments