Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/python-3.x/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 3.x 我可以使用pybind加载外部c++;dll和调用函数?_Python 3.x_Pybind11 - Fatal编程技术网

Python 3.x 我可以使用pybind加载外部c++;dll和调用函数?

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

我正在尝试与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)
这将返回带或不带参数的代码-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
。除此之外,正如我所说:我无法直接核实。