Skip to content

Commit fad677f

Browse files
committed
Refactor CDLL __init__ function
1 parent cf31798 commit fad677f

1 file changed

Lines changed: 48 additions & 36 deletions

File tree

Lib/ctypes/__init__.py

Lines changed: 48 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,8 @@ class CFunctionType(_CFuncPtr):
108108
return CFunctionType
109109

110110
if _os.name == "nt":
111-
from _ctypes import LoadLibrary as _dlopen
111+
# from _ctypes import LoadLibrary as _dlopen
112+
from _ctypes import LoadLibrary as _LoadLibrary
112113
from _ctypes import FUNCFLAG_STDCALL as _FUNCFLAG_STDCALL
113114

114115
_win_functype_cache = {}
@@ -137,6 +138,7 @@ class WinFunctionType(_CFuncPtr):
137138
WINFUNCTYPE.__doc__ = CFUNCTYPE.__doc__.replace("CFUNCTYPE", "WINFUNCTYPE")
138139

139140
elif _os.name == "posix":
141+
# from _ctypes import dlopen as _dlopen
140142
from _ctypes import dlopen as _dlopen
141143

142144
from _ctypes import sizeof, byref, addressof, alignment, resize
@@ -410,52 +412,62 @@ def __init__(self, name, mode=DEFAULT_MODE, handle=None,
410412
use_errno=False,
411413
use_last_error=False,
412414
winmode=None):
415+
class _FuncPtr(_CFuncPtr):
416+
_flags_ = self._func_flags_
417+
_restype_ = self._func_restype_
418+
if use_errno:
419+
_flags_ |= _FUNCFLAG_USE_ERRNO
420+
if use_last_error:
421+
_flags_ |= _FUNCFLAG_USE_LASTERROR
422+
423+
self._FuncPtr = _FuncPtr
413424
if name:
414425
name = _os.fspath(name)
415426

427+
if handle is None:
428+
self._handle = self._load_library(name, mode, winmode)
429+
else:
430+
self._handle = handle
431+
432+
if _os.name == "nt":
433+
def _load_library(self, name, mode, winmode):
434+
if winmode is not None:
435+
mode = winmode
436+
else:
437+
import nt as _nt
438+
mode = _nt._LOAD_LIBRARY_SEARCH_DEFAULT_DIRS
439+
# WINAPI LoadLibrary searches for a DLL if the given name
440+
# is not fully qualified with an explicit drive. For POSIX
441+
# compatibility, and because the DLL search path no longer
442+
# contains the working directory, begin by fully resolving
443+
# any name that contains a path separator.
444+
if name is not None and ('/' in name or '\\' in name):
445+
name = _nt._getfullpathname(name)
446+
mode |= _nt._LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR
447+
self._name = name
448+
return _LoadLibrary(self._name, mode)
449+
450+
else:
451+
def _load_library(self, name, mode, winmode):
452+
if _sys.platform.startswith("aix"):
453+
"""When the name contains ".a(" and ends with ")",
454+
e.g., "libFOO.a(libFOO.so)" - this is taken to be an
455+
archive(member) syntax for dlopen(), and the mode is adjusted.
456+
Otherwise, name is presented to dlopen() as a file argument.
457+
"""
458+
if name and name.endswith(")") and ".a(" in name:
459+
mode |= ( _os.RTLD_MEMBER | _os.RTLD_NOW )
416460
# If the filename that has been provided is an iOS/tvOS/watchOS
417461
# .fwork file, dereference the location to the true origin of the
418462
# binary.
419-
if name.endswith(".fwork"):
463+
if name and name.endswith(".fwork"):
420464
with open(name) as f:
421465
name = _os.path.join(
422466
_os.path.dirname(_sys.executable),
423467
f.read().strip()
424468
)
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 name is not None and ('/' 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
469+
self._name = name
470+
return _dlopen(name, mode)
459471

460472
def __repr__(self):
461473
return "<%s '%s', handle %x at %#x>" % \

0 commit comments

Comments
 (0)