我使用Python连接到一个旧数据库,并使用EHLLAPI DLL文件与我的终端仿真器对话。EHLLAPI使用一个单一的调用点接口,其中所有操作都是通过hllApi函数完成的。该函数只接受指针作为参数。我向模拟器发送数据没有问题。
问题是将值返回到第二个到第四个参数中的指针,而不是作为函数的返回值。如果您查看最后3行代码,您可以看到要从屏幕中提取一个字符串,我必须设置第二个字符串缓冲区,创建一个指针,将该指针传递给hllapi,解码返回的内容,然后将其放入原始字符串缓冲区中。
这看起来既混乱又低效。有没有一种更清洁、更有效的方法来做到这一点?
from ctypes import *
hllDll = WinDLL ("Ehlapi32.DLL")
hllApiProto = WINFUNCTYPE (c_int, c_void_p, c_void_p, c_void_p, c_void_p)
hllApiParams = (1, "p1", 0), (1, "p2", 0), (1, "p3",0), (1, "p4",0)
hllApi = hllApiProto (("hllapi", hllDll), hllApiParams)
sBuf = ""
hllRc = 0
def hllGetString(nRow, nCol, sLen):
global sBuf
sBuf2 = c_char_p (sBuf.encode('ascii')) # <----------- Is there a better way to do this? ---
hllApi (byref (c_int (8)), sBuf2, byref (c_int (sLen)), byref (c_int (hllRc))) # <----------
sBuf = sBuf2.value[0:sLen].decode('ascii') # <----------------------------------------------发布于 2022-07-08 23:18:34
我在没有示例原型或实际函数实现的情况下做了一些猜测,所以我做了一个。如果我猜错了,请提供你自己的答案,我会更新答案:
test.c
#include <stdio.h>
#include <memory.h>
__declspec(dllexport)
int __stdcall hllapi(void* p1, void* p2, void* p3, void* p4) {
printf("p1 = %d\n", *(int*)p1); // input (command code?)
int len = *(int*)p3; // length of p2 buffer
printf("p3 = %d\n", len);
memset(p2,'A',len); // Fill length of buffer
*(int*)p4 = 1; // return code output parameter?
return 0; // not used?
}如果实际的函数采用void*,那么您就无法摆脱转换,至少如果参数类型根据使用发生了更改。我猜想第一个参数是影响其余三个参数的命令代码,因此您不能使用void*来实现这种灵活性。最后一个参数似乎是一个输出参数,因此它需要在调用之后才能返回该值的存储。请注意,byref(c_int(hllRc))创建一个只存在于该代码行并在该代码行之后立即被释放(至少在CPython中)的值的ctype整数。
此外,要匹配char*类型的参数,如果要用Unicode (str)字符串开始和结束,仍然需要.encode()和.decode()三明治来生成bytes字符串。
test.py
from ctypes import *
hllDll = WinDLL ('./test')
hllApi = hllDll.hllapi
hllApi.argtypes = c_void_p, c_void_p, c_void_p, c_void_p
hllApi.restype = c_int
def hllGetString(nRow, nCol, sLen):
buf = create_string_buffer(sLen) # allocate storage for the buffer
hllRc = c_int() # allocate storage for return code (Rc?)
hllApi(byref(c_int(8)), buf, byref(c_int(sLen)), byref(hllRc))
return hllRc.value, buf.raw.decode('ascii')
print(hllGetString(1, 2, 10))输出:
p1 = 8
p3 = 10
(1, 'AAAAAAAAAA')https://stackoverflow.com/questions/72916553
复制相似问题