首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在Python中使用DLL将值返回到指针

在Python中使用DLL将值返回到指针
EN

Stack Overflow用户
提问于 2022-07-08 20:14:38
回答 1查看 69关注 0票数 0

我使用Python连接到一个旧数据库,并使用EHLLAPI DLL文件与我的终端仿真器对话。EHLLAPI使用一个单一的调用点接口,其中所有操作都是通过hllApi函数完成的。该函数只接受指针作为参数。我向模拟器发送数据没有问题。

问题是将值返回到第二个到第四个参数中的指针,而不是作为函数的返回值。如果您查看最后3行代码,您可以看到要从屏幕中提取一个字符串,我必须设置第二个字符串缓冲区,创建一个指针,将该指针传递给hllapi,解码返回的内容,然后将其放入原始字符串缓冲区中。

这看起来既混乱又低效。有没有一种更清洁、更有效的方法来做到这一点?

代码语言:javascript
复制
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') # <----------------------------------------------
EN

回答 1

Stack Overflow用户

发布于 2022-07-08 23:18:34

我在没有示例原型或实际函数实现的情况下做了一些猜测,所以我做了一个。如果我猜错了,请提供你自己的答案,我会更新答案:

test.c

代码语言:javascript
复制
#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

代码语言:javascript
复制
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))

输出:

代码语言:javascript
复制
p1 = 8
p3 = 10
(1, 'AAAAAAAAAA')
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/72916553

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档