如何获取dll消息 - 查看过程,然后将其重定向到Python Stdout



我试图弄清楚如何进行以及一般是否可行或不可行。

我与外部DLL一起控制我的机械延迟线。

此API具有内部过程,用于在单独的窗口中输出消息。我强烈希望抓住此消息流并出现在我的Python(Pyqt5(书面应用程序中。

API描述中有一个函数:

int LS_SetProcessMessagesProc(void *pProc);

函数返回0或1,如果没有错误或分别存在。

根据DLL描述它可以替换LSTEP API的内部消息触摸过程。

在等待主线消息中的LSTEP确认时,LSTEP API处理。如果要切换消息键入或用ONW代码替换,则可以使用SetProcessMessagesProc来使用回调。

pproc必须是没有参数的stdcall程序的指针:

void MyProcessMessages() {...}

示例:ls.setProcessMessagesProc(& myProcessMessages(;

作为例如,如果我们采用Python Stdout,我如何将消息发送给它?

我要去为了说明:

上的所有内容
  • [MSDN]:Enumwindows函数 - 列举屏幕上的所有窗口,并且每个窗口都称为 callback 函数 - 检查下一个子弹
  • [MSDN]:EnumwindowsProc回调函数 - 用于处理每个枚举窗口

是(一个更复杂的示例(您需要的内容:在外部 .dll 中定义的功能,需要调用另一个自定义函数(您在 python中编写了您的 python (,通过[python]:ctypes模块(on win (。

代码:

import ctypes
from ctypes import wintypes
try:
    from win32gui import GetWindowText
    pywin32_present = True
except ImportError:
    pywin32_present = False

def enum_windows_proc(hwnd, l_param):
    print("HWND: {}n".format(hwnd))
    if pywin32_present:
        txt = GetWindowText(hwnd)
        if txt and "MSCTFIME UI" not in txt and "Default IME" not in txt:
            print("  Window text: {}n".format(txt))
    return 1

def main():
    user32_dll = ctypes.windll.LoadLibrary("user32.dll")
    enum_windows = user32_dll.EnumWindows
    WND_ENUM_PROC_TYPE = ctypes.WINFUNCTYPE(wintypes.BOOL, wintypes.HWND, wintypes.LPARAM)
    enum_windows.argtypes = (WND_ENUM_PROC_TYPE, wintypes.LPARAM)
    enum_windows.restype = wintypes.BOOL
    enum_windows(WND_ENUM_PROC_TYPE(enum_windows_proc), wintypes.LPARAM(0))

if __name__ == "__main__":
    main()

注释

  • import S:
    • wintypes 是A ctypes 子模块,它定义了一堆 ms 特定数据(常数,结构,枚举,...(
    • [python]:Pywin32是 python c c win 函数,这基本上是一种更高级(和pythonic(的方法 ctypes 做。默认情况下,它不带有 python ,必须手动安装;在我们的示例中,这是可选的
  • def enum_windows_proc(hwnd, l_param):
    • 这是 BOOL CALLBACK EnumWindowsProc(_In_ HWND hwnd, _In_ LPARAM lParam);
    • python
    • 为每个窗口打印 hwnd (窗口句柄((请注意,将有很多这样的窗口,因为大多数窗口对用户都是"不可见的"(
    • 如果安装了 pywin32 模块,则将用于提取每个窗口的标题(标题(。当然,这也可以使用 ctypes 来完成,但要复杂一些
    • 标题过滤是避免打印无用的文本(对于大多数窗口(。如果您需要更多详细信息,请检查:[so]:使用过程名称
    • 获取另一个程序的窗口标题
  • main功能:
    • 首先,需要加载包含该函数的 .dll (在我们的情况下 user32.dll (。这是使用[MSDN]:LoadLibrary函数( ux :[man]:dlopen(完成的。另外,返回对象(user32_dll(的内部结构(下一行看起来很简单(是初始化的
    • 使用[msdn]的功能(或更好:一个指针(正在检索(enum_windows(:getProcAddress函数( ux :[man]:dlsym(
    • 接下来的3行代码用于让 python 知道有关加载功能指针的详细信息(返回类型和参数类型(。请注意,(在某些情况下(有一种更简单的方法(编码(来完成所有操作,但是出于学习目的,可以浏览整个过程
  • 最后,以我们的自定义函数为参数
  • 调用外部函数

由于会有很多输出(并且主要是内存地址(,所以我不会在这里粘贴它。

根据您在问题中粘贴的功能标题来解决您的问题,我们可以采用相同的方法(请注意,代码将不是工作复制/粘贴 ootb

import ctypes
from ctypes import wintypes
def my_process_messages():
    # Your code here (delete the next (`pass`) line)
    pass
dll_name = "your dll path (full or relative)"
dll_object = ctypes.windll.LoadLibrary(dll_name)
ls_set_process_messages_proc = dll_object.LS_SetProcessMessagesProc
PROCESS_MESSAGES_TYPE = ctypes.WINFUNCTYPE(None)
ls_set_process_messages_proc.argtypes = (PROCESS_MESSAGES_TYPE,)
ls_set_process_messages_proc.restype = ctypes.c_int
print("ls_set_process_messages_proc returned: {}n".format(ls_set_process_messages_proc(PROCESS_MESSAGES_TYPE(my_process_messages))))

注意:示例基于以下事实:外部 .dll

  • win 样式(使用 stdcall 调用justnuction(。如果那不是真的(它使用 cdecl (,您需要更改(为了严格的缘故,我要说两件事(:

    • ctypes.windll to ctypes.cdll
    • ctypes.WINFUNCTYPE to ctypes.CFUNCTYPE
  • 导出 c 样式函数(不是 c 哪个mangles函数名称(,我几乎可以肯定。但是,如果不是这种情况,那就对不起,这里无事可做。有关此主题的更多详细信息,请检查:[so]:Excel VBA,找不到DLL文件的DLL入口点。

阅读有关CTYPES教程的信息
加载动力 - 链路上线
从已加载的DLL访问功能
调用功能

Linux示例,使用标准C库的QSORT函数:

  1. 加载libc.so.6 DLL。

    from ctypes import *
    libc = CDLL("libc.so.6")
    
  2. 获取函数指针到qsort

    qsort = libc.qsort
    qsort.restype = None
    
  3. 创建回调函数的类型
    并实现Python回调功能。

    CMPFUNC = CFUNCTYPE(c_int, POINTER(c_int), POINTER(c_int))
    def py_cmp_func(a, b):
        return a[0] - b[0]
    cmp_func = CMPFUNC(py_cmp_func)
    
  4. 定义具有值的C型整数数组
    并使用qsort使用cmp_func对数组进行排序。

    IntArray5 = c_int * 5
    ia = IntArray5(5, 1, 7, 33, 99)
    qsort(ia, len(ia), sizeof(c_int), cmp_func)
    for i in ia:
        print(i)
    

输出

1 5 7 33 99

相关内容

最新更新