ctypes dll变量声明
ctypes dll declaration of variables
我正在尝试将以下函数与 ctypes 一起使用,但我确实遇到了如何正确声明所有参数和变量的问题。
C代码的文档如下,
/* global variables */
int main ()
char sDeviceSerialNumber[32];
FEUSB_GetScanListPara( 0, "Device-ID", sDeviceSerialNumber ) ;
sDeviceSerialNumber 应该是我在 Python 中需要进一步使用的函数的 return 值。
Python代码:
def FEUSB_GetScanListPara(iIndex, cPara):
libfeusb.FEUSB_GetScanListPara.argtypes = [ctypes.c_int,
ctypes.c_wchar_p,
ctypes.POINTER(ctypes.c_char_p)
]
libfeusb.FEUSB_GetScanListPara.restype = ctypes.c_int
iIndex = ctypes.c_int(iIndex)
cValue_buffer = ctypes.create_string_buffer(32)
cValue = ctypes.c_char_p(ctypes.addressof(cValue_buffer))
value = libfeusb.FEUSB_GetScanListPara(iIndex,
cPara,
ctypes.byref(cValue)
)
if __name__ == "__main__":
i = 0
RFID.FEUSB_GetScanListPara(i, "Device-ID")
当我用上面的代码调用函数时,我得到一个错误代码,FEUSB_ERR_UNKNOWN_PARAMETER,因此我假设我没有正确声明参数。
欢迎任何意见!
编辑 1
def FEUSB_GetScanListPara(iIndex, cPara):
libfeusb.FEUSB_GetScanListPara.argtypes = [ctypes.c_int,
ctypes.c_char_p,
ctypes.c_char_p
]
libfeusb.FEUSB_GetScanListPara.restype = ctypes.c_int
cValue = ctypes.create_string_buffer(32)
value = libfeusb.FEUSB_GetScanListPara(iIndex, cPara,
ctypes.byref(cValue))
print("1.0", cPara, "back value", " = ", value)
print("1.1", cPara, " = ", cValue.value)
print("######")
if __name__ == "__main__":
data = RFID.FEUSB_GetScanListPara(i, b"Device-ID")
Python 控制台:
FEUSB_ClearScanList = 0
FEUSB_Scan = 0
FEUSB_GetScanListSize = 1
Traceback (most recent call last):
File "C:\xxxxx.1_ObidRFID_test\OBID_RFID_06.py", line 265, in <module>
data = RFID.FEUSB_GetScanListPara(i, b"Device-ID")
File "C:\xxxxx.1_ObidRFID_test\OBID_RFID_06.py", line 89, in FEUSB_GetScanListPara
value = libfeusb.FEUSB_GetScanListPara(iIndex, cPara, ctypes.byref(cValue))
ArgumentError: argument 3: <class 'TypeError'>: wrong type
编辑 2
工作代码
def FEUSB_GetScanListPara(iIndex, cPara):
libfeusb.FEUSB_GetScanListPara.argtypes = [ctypes.c_int,
ctypes.c_char_p,
ctypes.c_char_p
]
libfeusb.FEUSB_GetScanListPara.restype = ctypes.c_int
cValue = ctypes.create_string_buffer(32)
return_value = libfeusb.FEUSB_GetScanListPara(0, b'Device-ID',
cValue)
您对 .argtypes
的声明将匹配以下的 C 原型:
int FEUSB_GetScanListPara(int, wchar_t*, char**)
您没有提供确切的 C 原型,但是从您的示例中可以看出:
FEUSB_GetScanListPara( 0, "Device-ID", sDeviceSerialNumber ) ;
并且知道 wchar_t*
不是通用接口参数,您实际上可能有简单的 char*
声明,例如:
int FEUSB_GetScanListPara(int, const char*, char*);
我假设第二个参数是输入参数,第三个参数是输出参数。请注意,c_char_p
对应于一个字节字符串,因此对 cPara
使用 b'DeviceID'
。此外,如果您必须分配缓冲区,则第 3 个参数不太可能是 char**
。如果 API 本身不返回指针,而是填充已分配的缓冲区,则 char*
和 ctypes.c_char_p
是合适的。您正确使用 create_string_buffer()
作为输出参数。
请注意,您不需要将 iIndex
包裹在 c_int
中。从 .argtypes
,ctypes
知道第一个参数是 c_int
并为您转换它。如果未提供 .argtypes
,这也是默认设置,但最好明确并提供 .argtypes
.
此代码应该有效。我没有要验证的 DLL:
import ctypes as ct
libfeusb = CDLL('./FESUB') # assuming in same directory
libfeusb.FEUSB_GetScanListPara.argtypes = ct.c_int, ct.c_char_p, ct.c_char_p
libfeusb.FEUSB_GetScanListPara.restype = ct.c_int
cValue = ct.create_string_buffer(32)
ret = libfeusb.FEUSB_GetScanListPara(0, b'Device-ID', cValue)
if ret == 0:
print(cValue.value)
else:
print('error:',ret)
如果您仍有问题,请使用 minimal, reproducible example 编辑您的问题。请务必提供真实的 C 原型。
我正在尝试将以下函数与 ctypes 一起使用,但我确实遇到了如何正确声明所有参数和变量的问题。
C代码的文档如下,
/* global variables */
int main ()
char sDeviceSerialNumber[32];
FEUSB_GetScanListPara( 0, "Device-ID", sDeviceSerialNumber ) ;
sDeviceSerialNumber 应该是我在 Python 中需要进一步使用的函数的 return 值。
Python代码:
def FEUSB_GetScanListPara(iIndex, cPara):
libfeusb.FEUSB_GetScanListPara.argtypes = [ctypes.c_int,
ctypes.c_wchar_p,
ctypes.POINTER(ctypes.c_char_p)
]
libfeusb.FEUSB_GetScanListPara.restype = ctypes.c_int
iIndex = ctypes.c_int(iIndex)
cValue_buffer = ctypes.create_string_buffer(32)
cValue = ctypes.c_char_p(ctypes.addressof(cValue_buffer))
value = libfeusb.FEUSB_GetScanListPara(iIndex,
cPara,
ctypes.byref(cValue)
)
if __name__ == "__main__":
i = 0
RFID.FEUSB_GetScanListPara(i, "Device-ID")
当我用上面的代码调用函数时,我得到一个错误代码,FEUSB_ERR_UNKNOWN_PARAMETER,因此我假设我没有正确声明参数。
欢迎任何意见!
编辑 1
def FEUSB_GetScanListPara(iIndex, cPara):
libfeusb.FEUSB_GetScanListPara.argtypes = [ctypes.c_int,
ctypes.c_char_p,
ctypes.c_char_p
]
libfeusb.FEUSB_GetScanListPara.restype = ctypes.c_int
cValue = ctypes.create_string_buffer(32)
value = libfeusb.FEUSB_GetScanListPara(iIndex, cPara,
ctypes.byref(cValue))
print("1.0", cPara, "back value", " = ", value)
print("1.1", cPara, " = ", cValue.value)
print("######")
if __name__ == "__main__":
data = RFID.FEUSB_GetScanListPara(i, b"Device-ID")
Python 控制台:
FEUSB_ClearScanList = 0
FEUSB_Scan = 0
FEUSB_GetScanListSize = 1
Traceback (most recent call last):
File "C:\xxxxx.1_ObidRFID_test\OBID_RFID_06.py", line 265, in <module>
data = RFID.FEUSB_GetScanListPara(i, b"Device-ID")
File "C:\xxxxx.1_ObidRFID_test\OBID_RFID_06.py", line 89, in FEUSB_GetScanListPara
value = libfeusb.FEUSB_GetScanListPara(iIndex, cPara, ctypes.byref(cValue))
ArgumentError: argument 3: <class 'TypeError'>: wrong type
编辑 2
工作代码
def FEUSB_GetScanListPara(iIndex, cPara):
libfeusb.FEUSB_GetScanListPara.argtypes = [ctypes.c_int,
ctypes.c_char_p,
ctypes.c_char_p
]
libfeusb.FEUSB_GetScanListPara.restype = ctypes.c_int
cValue = ctypes.create_string_buffer(32)
return_value = libfeusb.FEUSB_GetScanListPara(0, b'Device-ID',
cValue)
您对 .argtypes
的声明将匹配以下的 C 原型:
int FEUSB_GetScanListPara(int, wchar_t*, char**)
您没有提供确切的 C 原型,但是从您的示例中可以看出:
FEUSB_GetScanListPara( 0, "Device-ID", sDeviceSerialNumber ) ;
并且知道 wchar_t*
不是通用接口参数,您实际上可能有简单的 char*
声明,例如:
int FEUSB_GetScanListPara(int, const char*, char*);
我假设第二个参数是输入参数,第三个参数是输出参数。请注意,c_char_p
对应于一个字节字符串,因此对 cPara
使用 b'DeviceID'
。此外,如果您必须分配缓冲区,则第 3 个参数不太可能是 char**
。如果 API 本身不返回指针,而是填充已分配的缓冲区,则 char*
和 ctypes.c_char_p
是合适的。您正确使用 create_string_buffer()
作为输出参数。
请注意,您不需要将 iIndex
包裹在 c_int
中。从 .argtypes
,ctypes
知道第一个参数是 c_int
并为您转换它。如果未提供 .argtypes
,这也是默认设置,但最好明确并提供 .argtypes
.
此代码应该有效。我没有要验证的 DLL:
import ctypes as ct
libfeusb = CDLL('./FESUB') # assuming in same directory
libfeusb.FEUSB_GetScanListPara.argtypes = ct.c_int, ct.c_char_p, ct.c_char_p
libfeusb.FEUSB_GetScanListPara.restype = ct.c_int
cValue = ct.create_string_buffer(32)
ret = libfeusb.FEUSB_GetScanListPara(0, b'Device-ID', cValue)
if ret == 0:
print(cValue.value)
else:
print('error:',ret)
如果您仍有问题,请使用 minimal, reproducible example 编辑您的问题。请务必提供真实的 C 原型。