我可以使用 pybind 加载外部 c++ dll 并调用函数吗?
Can I use pybind to load an external c++ dll and call functions?
我正在尝试连接 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 = 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)
这个 returns 代码 -3 有或没有参数。根据文档 -3 指的是 "Port cannot be opened"。但我可以看到端口并使用 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))
我正在尝试连接 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 = 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)
这个 returns 代码 -3 有或没有参数。根据文档 -3 指的是 "Port cannot be opened"。但我可以看到端口并使用 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))