@@ -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 = {}
@@ -410,52 +410,59 @@ def __init__(self, name, mode=DEFAULT_MODE, handle=None,
410410 use_errno = False ,
411411 use_last_error = False ,
412412 winmode = None ):
413+ class _FuncPtr (_CFuncPtr ):
414+ _flags_ = self ._func_flags_
415+ _restype_ = self ._func_restype_
416+ if use_errno :
417+ _flags_ |= _FUNCFLAG_USE_ERRNO
418+ if use_last_error :
419+ _flags_ |= _FUNCFLAG_USE_LASTERROR
420+
421+ self ._FuncPtr = _FuncPtr
413422 if name :
414423 name = _os .fspath (name )
415424
425+ self ._handle = self ._load_library (name , mode , handle , winmode )
426+
427+ if _os .name == "nt" :
428+ def _load_library (self , name , mode , handle , winmode ):
429+ if winmode is None :
430+ import nt as _nt
431+ winmode = _nt ._LOAD_LIBRARY_SEARCH_DEFAULT_DIRS
432+ # WINAPI LoadLibrary searches for a DLL if the given name
433+ # is not fully qualified with an explicit drive. For POSIX
434+ # compatibility, and because the DLL search path no longer
435+ # contains the working directory, begin by fully resolving
436+ # any name that contains a path separator.
437+ if name is not None and ('/' in name or '\\ ' in name ):
438+ name = _nt ._getfullpathname (name )
439+ winmode |= _nt ._LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR
440+ self ._name = name
441+ if handle is not None :
442+ return handle
443+ return _LoadLibrary (self ._name , winmode )
444+
445+ else :
446+ def _load_library (self , name , mode , handle , winmode ):
416447 # If the filename that has been provided is an iOS/tvOS/watchOS
417448 # .fwork file, dereference the location to the true origin of the
418449 # binary.
419- if name .endswith (".fwork" ):
450+ if name and name .endswith (".fwork" ):
420451 with open (name ) as f :
421452 name = _os .path .join (
422453 _os .path .dirname (_sys .executable ),
423454 f .read ().strip ()
424455 )
425-
426- self ._name = name
427- flags = self ._func_flags_
428- if use_errno :
429- flags |= _FUNCFLAG_USE_ERRNO
430- if use_last_error :
431- flags |= _FUNCFLAG_USE_LASTERROR
432- if _sys .platform .startswith ("aix" ):
433- """When the name contains ".a(" and ends with ")",
434- e.g., "libFOO.a(libFOO.so)" - this is taken to be an
435- archive(member) syntax for dlopen(), and the mode is adjusted.
436- Otherwise, name is presented to dlopen() as a file argument.
437- """
438- if name and name .endswith (")" ) and ".a(" in name :
439- mode |= ( _os .RTLD_MEMBER | _os .RTLD_NOW )
440- if _os .name == "nt" :
441- if winmode is not None :
442- mode = winmode
443- else :
444- import nt
445- mode = nt ._LOAD_LIBRARY_SEARCH_DEFAULT_DIRS
446- if '/' in name or '\\ ' in name :
447- self ._name = nt ._getfullpathname (self ._name )
448- mode |= nt ._LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR
449-
450- class _FuncPtr (_CFuncPtr ):
451- _flags_ = flags
452- _restype_ = self ._func_restype_
453- self ._FuncPtr = _FuncPtr
454-
455- if handle is None :
456- self ._handle = _dlopen (self ._name , mode )
457- else :
458- self ._handle = handle
456+ if _sys .platform .startswith ("aix" ):
457+ """When the name contains ".a(" and ends with ")",
458+ e.g., "libFOO.a(libFOO.so)" - this is taken to be an
459+ archive(member) syntax for dlopen(), and the mode is adjusted.
460+ Otherwise, name is presented to dlopen() as a file argument.
461+ """
462+ if name and name .endswith (")" ) and ".a(" in name :
463+ mode |= _os .RTLD_MEMBER | _os .RTLD_NOW
464+ self ._name = name
465+ return _dlopen (name , mode )
459466
460467 def __repr__ (self ):
461468 return "<%s '%s', handle %x at %#x>" % \
0 commit comments