【发布时间】:2020-01-29 13:27:05
【问题描述】:
我正在尝试与仅提供 dll(c++) 的 PoS 终端进行交互。我可以使用pybind加载dll并通过一些代码调用api函数吗:
import pybind11
mydll = pybind.load("/path/to/dll")
mydll.api_call(param1,param2)
我在 ctypes 中尝试了以下代码。但无法让 API 正常工作或出现清晰的错误。
from ctypes import *
import ctypes.wintypes as wintypes
mydll = windll.LoadLibrary("C:\madaapi_v1_7.dll")
mydll.api_GetCOMTerminalID.argtypes = POINTER(c_char_p), POINTER(wintypes.DWORD), POINTER(c_byte), POINTER(c_byte),POINTER(c_byte),POINTER(c_char_p),POINTER(c_int),POINTER(c_byte)
bPort,dwBaudRate,bParity,bDataBits,bStopBits, inReqBuff, inReqlen, terminal_id = c_char_p(b'COM3'),wintypes.DWORD(38400),c_byte(0),c_byte(8),c_byte(1),c_char_p(b'07!'),c_int(3),c_byte()
conn = mydll.api_GetCOMTerminalID(byref(bPort),byref(dwBaudRate),byref(bParity),byref(bDataBits),byref(bStopBits),byref(inReqBuff),byref(inReqlen),byref(terminal_id))
print(conn)
这将返回带有或不带有参数的代码 -3。根据文档 -3 是指“无法打开端口”。但我可以看到端口并使用 PySerial 打开它。
根据 dll 文档,这些是输入数据类型:
int api_GetCOMTerminalID (BYTE bPort, DWORD dwBaudRate, BYTE bParity, BYTE bDataBits, BYTE bStopBits, unsigned char* inReqBuff, int *inReqLen, BYTE *terminalId)
这是一个示例调用:
api_GetCOMTerminalID (3,38400,0,8,0,”07!”,3)
【问题讨论】:
-
不是这样,因为 pybind11 没有运行时组件(这是它的主要卖点)。但是您要问的正是 ctypes 提供的功能。您不想使用 ctypes 的原因是该函数具有 C++(而不是 C)签名吗?
-
@WimLavrijsen 我已经用我在 ctypes 中尝试过的代码编辑了这个问题。但它没有用。
-
函数的签名是什么?如果所有参数都需要 byref(尤其是端口的命名),我会感到惊讶。
-
我用函数所需的数据类型再次编辑了我的问题。我不知道如何在调用中声明、分配和传递它。我尝试了很多方法,只得到错误和错误。
-
是的,所以那些
byrefs 不应该出现在大多数争论中。在上面的mydll.api_GetCOMTerminalID中,删除除inReqlen和terminal_id上的所有byrefs。由于 byref 传递的是一个指针,因此在其他情况下您传递的是或多或少的随机值,而不是预期的值。
标签: python-3.x pybind11