def init_kernel32(kernel32=None):
"""Load a unique instance of WinDLL into memory, set arg/return types, and get stdout/err handles.
1. Since we are setting DLL function argument types and return types, we need to maintain our own instance of
kernel32 to prevent overriding (or being overwritten by) user's own changes to ctypes.windll.kernel32.
2. While we're doing all this we might as well get the handles to STDOUT and STDERR streams.
3. If either stream has already been replaced set return value to INVALID_HANDLE_VALUE to indicate it shouldn't be
replaced.
:raise AttributeError: When called on a non-Windows platform.
:param kernel32: Optional mock kernel32 object. For testing.
:return: Loaded kernel32 instance, stderr handle (int), stdout handle (int).
:rtype: tuple
"""
if not kernel32:
kernel32 = ctypes.LibraryLoader(ctypes.WinDLL).kernel32 # Load our own instance. Unique memory address.
kernel32.GetStdHandle.argtypes = [ctypes.c_ulong]
kernel32.GetStdHandle.restype = ctypes.c_void_p
kernel32.GetConsoleScreenBufferInfo.argtypes = [
ctypes.c_void_p,
ctypes.POINTER(ConsoleScreenBufferInfo),
]
kernel32.GetConsoleScreenBufferInfo.restype = ctypes.c_long
# Get handles.
if hasattr(sys.stderr, '_original_stream'):
stderr = INVALID_HANDLE_VALUE
else:
stderr = kernel32.GetStdHandle(STD_ERROR_HANDLE)
if hasattr(sys.stdout, '_original_stream'):
stdout = INVALID_HANDLE_VALUE
else:
stdout = kernel32.GetStdHandle(STD_OUTPUT_HANDLE)
return kernel32, stderr, stdout
python类LibraryLoader()的实例源码
def init_kernel32(kernel32=None):
"""Load a unique instance of WinDLL into memory, set arg/return types, and get stdout/err handles.
1. Since we are setting DLL function argument types and return types, we need to maintain our own instance of
kernel32 to prevent overriding (or being overwritten by) user's own changes to ctypes.windll.kernel32.
2. While we're doing all this we might as well get the handles to STDOUT and STDERR streams.
3. If either stream has already been replaced set return value to INVALID_HANDLE_VALUE to indicate it shouldn't be
replaced.
:raise AttributeError: When called on a non-Windows platform.
:param kernel32: Optional mock kernel32 object. For testing.
:return: Loaded kernel32 instance, stderr handle (int), stdout handle (int).
:rtype: tuple
"""
if not kernel32:
kernel32 = ctypes.LibraryLoader(ctypes.WinDLL).kernel32 # Load our own instance. Unique memory address.
kernel32.GetStdHandle.argtypes = [ctypes.c_ulong]
kernel32.GetStdHandle.restype = ctypes.c_void_p
kernel32.GetConsoleScreenBufferInfo.argtypes = [
ctypes.c_void_p,
ctypes.POINTER(ConsoleScreenBufferInfo),
]
kernel32.GetConsoleScreenBufferInfo.restype = ctypes.c_long
# Get handles.
if hasattr(sys.stderr, '_original_stream'):
stderr = INVALID_HANDLE_VALUE
else:
stderr = kernel32.GetStdHandle(STD_ERROR_HANDLE)
if hasattr(sys.stdout, '_original_stream'):
stdout = INVALID_HANDLE_VALUE
else:
stdout = kernel32.GetStdHandle(STD_OUTPUT_HANDLE)
return kernel32, stderr, stdout