@@ -107,7 +107,7 @@ class CFunctionType(_CFuncPtr):
107107 return CFunctionType
108108
109109if _os .name == "nt" :
110- from _ctypes import LoadLibrary as _dlopen
110+ from _ctypes import LoadLibrary as _LoadLibrary
111111 from _ctypes import FUNCFLAG_STDCALL as _FUNCFLAG_STDCALL
112112
113113 _win_functype_cache = {}
@@ -344,52 +344,59 @@ def __init__(self, name, mode=DEFAULT_MODE, handle=None,
344344 use_errno = False ,
345345 use_last_error = False ,
346346 winmode = None ):
347+ class _FuncPtr (_CFuncPtr ):
348+ _flags_ = self ._func_flags_
349+ _restype_ = self ._func_restype_
350+ if use_errno :
351+ _flags_ |= _FUNCFLAG_USE_ERRNO
352+ if use_last_error :
353+ _flags_ |= _FUNCFLAG_USE_LASTERROR
354+
355+ self ._FuncPtr = _FuncPtr
347356 if name :
348357 name = _os .fspath (name )
349358
359+ self ._handle = self ._load_library (name , mode , handle , winmode )
360+
361+ if _os .name == "nt" :
362+ def _load_library (self , name , mode , handle , winmode ):
363+ if winmode is None :
364+ import nt as _nt
365+ winmode = _nt ._LOAD_LIBRARY_SEARCH_DEFAULT_DIRS
366+ # WINAPI LoadLibrary searches for a DLL if the given name
367+ # is not fully qualified with an explicit drive. For POSIX
368+ # compatibility, and because the DLL search path no longer
369+ # contains the working directory, begin by fully resolving
370+ # any name that contains a path separator.
371+ if name is not None and ('/' in name or '\\ ' in name ):
372+ name = _nt ._getfullpathname (name )
373+ winmode |= _nt ._LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR
374+ self ._name = name
375+ if handle is not None :
376+ return handle
377+ return _LoadLibrary (self ._name , winmode )
378+
379+ else :
380+ def _load_library (self , name , mode , handle , winmode ):
350381 # If the filename that has been provided is an iOS/tvOS/watchOS
351382 # .fwork file, dereference the location to the true origin of the
352383 # binary.
353- if name .endswith (".fwork" ):
384+ if name and name .endswith (".fwork" ):
354385 with open (name ) as f :
355386 name = _os .path .join (
356387 _os .path .dirname (_sys .executable ),
357388 f .read ().strip ()
358389 )
359-
360- self ._name = name
361- flags = self ._func_flags_
362- if use_errno :
363- flags |= _FUNCFLAG_USE_ERRNO
364- if use_last_error :
365- flags |= _FUNCFLAG_USE_LASTERROR
366- if _sys .platform .startswith ("aix" ):
367- """When the name contains ".a(" and ends with ")",
368- e.g., "libFOO.a(libFOO.so)" - this is taken to be an
369- archive(member) syntax for dlopen(), and the mode is adjusted.
370- Otherwise, name is presented to dlopen() as a file argument.
371- """
372- if name and name .endswith (")" ) and ".a(" in name :
373- mode |= ( _os .RTLD_MEMBER | _os .RTLD_NOW )
374- if _os .name == "nt" :
375- if winmode is not None :
376- mode = winmode
377- else :
378- import nt
379- mode = nt ._LOAD_LIBRARY_SEARCH_DEFAULT_DIRS
380- if '/' in name or '\\ ' in name :
381- self ._name = nt ._getfullpathname (self ._name )
382- mode |= nt ._LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR
383-
384- class _FuncPtr (_CFuncPtr ):
385- _flags_ = flags
386- _restype_ = self ._func_restype_
387- self ._FuncPtr = _FuncPtr
388-
389- if handle is None :
390- self ._handle = _dlopen (self ._name , mode )
391- else :
392- self ._handle = handle
390+ if _sys .platform .startswith ("aix" ):
391+ """When the name contains ".a(" and ends with ")",
392+ e.g., "libFOO.a(libFOO.so)" - this is taken to be an
393+ archive(member) syntax for dlopen(), and the mode is adjusted.
394+ Otherwise, name is presented to dlopen() as a file argument.
395+ """
396+ if name and name .endswith (")" ) and ".a(" in name :
397+ mode |= _os .RTLD_MEMBER | _os .RTLD_NOW
398+ self ._name = name
399+ return _dlopen (name , mode )
393400
394401 def __repr__ (self ):
395402 return "<%s '%s', handle %x at %#x>" % \
0 commit comments