我正在试图弄清楚如何进行以及一般是否可行。
我使用外部DLL来控制机械延迟线。
此API具有单独窗口中的消息输出的内部过程。我非常希望能够捕获这个消息流并出现在我的python(PyQT5)编写的应用程序中。
在API描述中有一个函数:
int LS_SetProcessMessagesProc(void *pProc);
如果没有错误或者它存在,函数返回0或1。
根据dll描述 它可以替换LStep API的内部消息调度过程。
LStep API在等待确认主线程消息中的LStep时进行处理。如果要切换Message-Dispatching或使用onw代码替换,可以使用SetProcessMessagesProc来使用回调过程。
pProc必须是没有参数的stdcall过程的指针:
void MyProcessMessages() {...}
实施例: LS.SetProcessMessagesProc(安培; MyProcessMessages);
例如,如果我们使用python stdout,我该如何将消息发送给它?
答案 0 :(得分:1)
了解ctypes tutorial
加载动态链接程序库
从加载的dll访问功能
调用函数
Linux示例,它使用标准C库的qsort函数:
加载libc.so.6
dll。
from ctypes import *
libc = CDLL("libc.so.6")
获取指向qsort
的函数指针。
qsort = libc.qsort
qsort.restype = None
创建回调函数的类型
并实现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)
使用值
定义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
答案 1 :(得分:1)
我将在以下内容中说明一切:
这是你需要的(一个稍微复杂的例子):在外部 .dll 中定义的函数,它需要调用另一个自定义函数(由你在 Python中编写)),通过[Python]: ctypes module(在 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:
def enum_windows_proc(hwnd, l_param):
:
BOOL CALLBACK EnumWindowsProc(_In_ HWND hwnd, _In_ LPARAM lParam);
main
功能:
user32_dll
)的内部结构(下一行看起来如此简单)enum_windows
)
由于会有很多输出(主要是内存地址),我不会在这里粘贴。
根据您在问题中粘贴的功能标题来解决您的问题,我们可以采用相同的方法(请注意,代码将不工作复制/粘贴 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 调用约定)。如果那不是真的(它使用 cdecl ),你需要改变(为了严格起见,我会说两件事):
ctypes.windll
至ctypes.cdll
ctypes.WINFUNCTYPE
至ctypes.CFUNCTYPE
导出 C 样式函数(不 C ++ ,这会破坏函数名称),我几乎100%肯定。但是,如果情况不是这样的话,对不起,这里无事可做。有关此主题的更多详细信息,请查看:[SO]: Excel VBA, Can't Find DLL Entry Point from a DLL file。