Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/typo3/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 使用ctypes.sizeof时,ctypes定义的PROCESSENTRY32产生不正确的大小_Python_Winapi_Ctypes - Fatal编程技术网

Python 使用ctypes.sizeof时,ctypes定义的PROCESSENTRY32产生不正确的大小

Python 使用ctypes.sizeof时,ctypes定义的PROCESSENTRY32产生不正确的大小,python,winapi,ctypes,Python,Winapi,Ctypes,这是我的结构定义;一些初步说明是,有/没有\u pack\u8时,结构不会显示正确的大小,\u pack\u8=1也不会显示正确的大小。我之所以提出这个大小问题,是因为Process32First在调用后设置了ERROR\u BAD\u LENGTH错误代码;我看不出为什么会是快照本身 class PROCESSENTRY32(ctypes.Structure): _pack_ = 8 _fields_ = [ ("dwSize",

这是我的结构定义;一些初步说明是,有/没有
\u pack\u8
时,结构不会显示正确的大小,
\u pack\u8=1
也不会显示正确的大小。我之所以提出这个大小问题,是因为
Process32First
在调用后设置了
ERROR\u BAD\u LENGTH
错误代码;我看不出为什么会是快照本身

class PROCESSENTRY32(ctypes.Structure):
    _pack_ = 8
    _fields_ = [
            ("dwSize",              ctypes.c_ulong),
            ("cntUsage",            ctypes.c_ulong),
            ("th32ProcessID",       ctypes.c_ulong),
            ("th32DefaultHeapID",   ctypes.POINTER(ctypes.c_uint64)),
            ("th32ModuleID",        ctypes.c_ulong),
            ("cntThreads",          ctypes.c_ulong),
            ("th32ParentProcessID", ctypes.c_ulong),
            ("pcPriClassBase",      ctypes.c_long),
            ("dwFlags",             ctypes.c_ulong),
            ("szExeFile",           ctypes.c_char*MAX_PATH)
            ]
ctypes\u configuration\u param\u select
仅选择
\ctypes\u configuration
中的预设值(如果该值不正确)或采用用户给定的输入。在此之前,在
import\u winapi\u调用中,参数和返回类型分别设置为
ctypes.c\u voidp
ctypes.POINTER(PROCESSENTRY32)
,指向winapi定义。返回类型为
ctypes.c_int
,表示
BOOL

def process32_first(snapshot_handle, process_entry_pointer, _ctypes_configuration=(
                    ("hSnapshot", (ctypes.c_voidp, True)),
                    ("lppe", (ctypes.POINTER(PROCESSENTRY32), True))
                   )):
    process32_first = import_winapi_function(
        "kernel32",
        "Process32First",
        argtypes_from_ctypes_configuration(_ctypes_configuration),
        ctypes.c_int
    )
    return process32_first(
        ctypes_configuration_param_select(_ctypes_configuration, 0) or snapshot_handle,
        ctypes_configuration_param_select(_ctypes_configuration, 1) or process_entry_pointer
    )
下面是函数的实际用法和结构的定义
debug\u fn
只是一个包装器,它将实际的函数调用夹在两个GetLastError调用之间,表示前后错误代码

总之,
debug\u fn(process32\u first,…)
调用会产生一个长度为24/error\u BAD\u的调用后错误代码,我将其归因于ctypes错误调整了
PROCESSENTRY32
/
pe
结构

我怎样才能解决这个问题

编辑:

这里有
ctypes\u configuration\u param\u select
argtypes\u from\u ctypes\u configuration
import\u winapi\u function
winapi function
debug\u fn

if __name__ == "__main__":
    snapshot = debug_fn(create_toolhelp32_snapshot, 0x2, 0)
    pe = PROCESSENTRY32()
    pe.dwSize = ctypes.sizeof(PROCESSENTRY32)
    debug_fn(process32_first, snapshot, ctypes.pointer(pe))
class WinAPIFunction(object):
    def __init__(self, module, name, handle, restype, argtypes):
        self.module = module
        self.name = name
        self.handle = handle
        self.argtypes = argtypes
        self.restype = restype 
    def __repr__(self):
        return f"<{self.module}.{self.name} @ {hex(self.handle)}>"
    __str__ = __repr__
    def __call__(self, *args):
        return ctypes.WINFUNCTYPE(self.restype, *self.argtypes)(self.handle)(*args)
import\u winapi\u函数
定义:

def argtypes_from_ctypes_configuration(ctypes_configuration):
    return tuple(v[0] for _, v in ctypes_configuration)

def ctypes_configuration_param_select(ctypes_configuration, idx):
    return ctypes_configuration[idx][1][1] if ctypes_configuration[idx][1][1] is not True else False
def import_winapi_function(namespace, name, argtypes, restype, is_unicode=UNICODE):
    gle = function_cache['kernel32.GetLastError']
    sle = function_cache['kernel32.SetLastError']
    gpa = function_cache['kernel32.GetProcAddress']
    gmh = function_cache['kernel32.GetModuleHandleA']

    name += "W" if is_unicode else "A"
    qual_fn_name = f"{namespace}.{name}"
    if qual_fn_name in function_cache:
        return function_cache[qual_fn_name]
    namespace_handle = gmh(create_string(namespace, False))
    if gle() == 127:
        sle(0)
        raise LookupError(f"Module: {namespace} doesn't exist.")
    function_handle = gpa(namespace_handle, create_string(name, False))
    if gle() != 127:
        function_cache[qual_fn_name] = WinAPIFunction(namespace, name, function_handle, restype, argtypes)
        return function_cache[qual_fn_name]
    sle(0) 
    name = name[:-1]
    qual_fn_name = qual_fn_name[:-1]
    if qual_fn_name in function_cache:
        return function_cache[qual_fn_name]
    function_handle = gpa(namespace_handle, create_string(name, False))
    if gle() == 127:
        sle(0)
        raise LookupError(f"Function: {namespace}.{name} doesn't exist.")
    function_cache[qual_fn_name] = WinAPIFunction(namespace, name, function_handle, restype, argtypes)
    return function_cache[qual_fn_name]
WinAPI函数定义:

def argtypes_from_ctypes_configuration(ctypes_configuration):
    return tuple(v[0] for _, v in ctypes_configuration)

def ctypes_configuration_param_select(ctypes_configuration, idx):
    return ctypes_configuration[idx][1][1] if ctypes_configuration[idx][1][1] is not True else False
def import_winapi_function(namespace, name, argtypes, restype, is_unicode=UNICODE):
    gle = function_cache['kernel32.GetLastError']
    sle = function_cache['kernel32.SetLastError']
    gpa = function_cache['kernel32.GetProcAddress']
    gmh = function_cache['kernel32.GetModuleHandleA']

    name += "W" if is_unicode else "A"
    qual_fn_name = f"{namespace}.{name}"
    if qual_fn_name in function_cache:
        return function_cache[qual_fn_name]
    namespace_handle = gmh(create_string(namespace, False))
    if gle() == 127:
        sle(0)
        raise LookupError(f"Module: {namespace} doesn't exist.")
    function_handle = gpa(namespace_handle, create_string(name, False))
    if gle() != 127:
        function_cache[qual_fn_name] = WinAPIFunction(namespace, name, function_handle, restype, argtypes)
        return function_cache[qual_fn_name]
    sle(0) 
    name = name[:-1]
    qual_fn_name = qual_fn_name[:-1]
    if qual_fn_name in function_cache:
        return function_cache[qual_fn_name]
    function_handle = gpa(namespace_handle, create_string(name, False))
    if gle() == 127:
        sle(0)
        raise LookupError(f"Function: {namespace}.{name} doesn't exist.")
    function_cache[qual_fn_name] = WinAPIFunction(namespace, name, function_handle, restype, argtypes)
    return function_cache[qual_fn_name]
如果你想复制我的代码;然后,您只需要将
函数\u cache
与上述代码片段放在一起:

def debug_fn(fn, *args, **kwargs):
    gle = get_last_error  # changeable
    print(f"\n{fn}:")
    print(f"\tget_last_error: {gle()}")
    res = fn(*args, **kwargs)
    print(f"\tret. code: {res}")
    print(f"\tget_last_error: {gle()}\n")
    return res

UNICODE
在我的环境中设置为True。

结构的
szExeFile
成员应该是
TCHAR
(或者最好是
WCHAR
,正如我在其他地方被告知的那样)而不是定义和(请参阅
CHAR
)此处定义的
CHAR

请将所有代码发布为缺失部分(ypu正试图描述它们的功能),可能包含您错误地认为不相关的关键数据。不幸的是,这不是一个mcve。mcve应该包含结构定义、kernel32.dll加载、
Process32First
函数(和其他函数)定义和加载、参数初始化和调用,因此最后(looong)代码段中没有任何内容。但最重要的事实是,它应该适用于其他人的解释器;有一些很长很复杂的函数。虽然我已经编辑并包含了所有内容(我相信),但您需要使示例正常工作。如果您使用
Process32FirstW
函数,您必须使用宽字符(
ctypes.c_wchar
,而不是
ctypes.c_char
),或者更好(
ctypes.wintypes.wchar
),因此
)。这是一个,我不确定是否还有其他的。在
ctypes.c_wchar
ctypes.wintypes.wchar
之间有什么不同?