Python 3.x 我可以使用pybind加载外部c++;dll和调用函数?
我正在尝试与PoS终端接口,它只提供一个dll(c++)。我是否可以使用pybind加载dll并通过以下代码调用api函数:Python 3.x 我可以使用pybind加载外部c++;dll和调用函数?,python-3.x,pybind11,Python 3.x,Pybind11,我正在尝试与PoS终端接口,它只提供一个dll(c++)。我是否可以使用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 = w
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)
我无法访问您正在使用的代码,但假设您发布的签名是正确的:
int api_GetCOMTerminalID (BYTE bPort, DWORD dwBaudRate, BYTE bParity, BYTE bDataBits, BYTE bStopBits, unsigned char* inReqBuff, int *inReqLen, BYTE *terminalId)
然后,以下ctypes代码将获得所有正确的类型:
from ctypes import *
import ctypes.wintypes as wintypes
BYTE = wintypes.BYTE
DWORD = wintypes.DWORD
c_uchar_p = POINTER(c_ubyte)
c_int_p = POINTER(c_int)
c_BYTE_p = POINTER(BYTE)
mydll = windll.LoadLibrary("C:\madaapi_v1_7.dll")
mydll.api_GetCOMTerminalID.argtypes = \
(BYTE, # BYTE bPort
DWORD, # DWORD dwBaudRate
BYTE, # BYTE bParity
BYTE, # BYTE bDataBits
BYTE, # BYTE bStopBits
c_uchar_p, # unsigned char* inReqBuff
c_int_p, # int *inReqLen
c_BYTE_p, # BYTE *terminalId
mydll.api_GetCOMTerminalID.restype = c_int
用法和示例:
bPort, dwBaudRate, bParity, bDataBits, bStopBits = \
BYTE(3), DWORD(38400), BYTE(0), BYTE(8), BYTE(0)
inReq = b'07!'
inReqBuff = (c_ubyte * len(inReq))()
for i in range(len(inReq)):
inReqBuff[i] = int(inReq[i])
inReqLen = c_int(3)
terminal_id = BYTE(0)
conn = mydll.api_GetCOMTerminalID(bPort, dwBaudRate, bParity, bDataBits, bStopBits,
inReqBuff, byref(inReqLen), byref(terminal_id))
并非如此,因为pybind11没有运行时组件(这是它的主要卖点)。但您所问的正是ctypes提供的功能。为什么你不想使用cType函数有一个C++(而不是C)签名?@ WimLavij森我用我在CyType中尝试的代码编辑了这个问题。但它不起作用。函数的签名是什么?如果所有参数都需要byref(特别是端口的命名),我会感到惊讶。我已经用函数所需的数据类型再次编辑了我的问题。我不知道如何在通话中声明、分配和传递。我尝试了很多方法,只得到了错误和错误。是的,所以那些
byref
s不应该出现在大多数参数中。在上面的mydll.api\u GetCOMTerminalID
中,删除所有byref
s,但在eqlen和终端id
上的除外。由于byref传递指针,因此在其他情况下,您传递的是或多或少的随机值,而不是预期的值。另外,您能否告诉我如果API返回类型是char array buffer,则在func.argstype中声明什么数据类型?对于返回类型,您需要设置func.restype
,而不是func.argtypes
,那你真的不明白吗?如果返回类型为,则指针(c_ubyte)
将起作用。或者您是指字符数组输出参数(即char**
或unsigned char**
)?我把问题框定错了。谢谢你的帮助。我知道如何在通话中使用正确的类型。从过去10天以来,我一直在寻求帮助。你的解决方案成功了。还有一件事,在API调用后,终端id是c\u字节(48)
,为了转换为人类可读的,我使用terminal\u id.value
并打印了48
。我不知道它是否是真正的终端id。我无法直接验证,但是是的,这就是终端id应该如何返回的,所以我希望它是正确的。另一个我不想说得更明确的原因是,BYTE
是无符号字符的typedef,而48
是ASCII中的'0'
。零可以表示“第一”(预期),但也可以表示“错误”(即失败)。检查文档,如果没有任何相关说明,我会打开另一个文档,看看您是否得到49
。除此之外,正如我所说:我无法直接核实。