首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >ctypes变量的dll声明

ctypes变量的dll声明
EN

Stack Overflow用户
提问于 2021-09-28 20:02:50
回答 1查看 53关注 0票数 0

我正在尝试将以下函数与ctype一起使用,但我确实遇到了如何正确声明所有参数和变量的问题。

C代码的文档如下:

代码语言:javascript
复制
/* global variables */

int main ()

char sDeviceSerialNumber[32];

FEUSB_GetScanListPara( 0, "Device-ID", sDeviceSerialNumber ) ;

sDeviceSerialNumber应该是函数的返回值,我需要在Python中进一步使用它。

Python代码:

代码语言:javascript
复制
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

代码语言:javascript
复制
    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控制台:

代码语言:javascript
复制
FEUSB_ClearScanList =  0
FEUSB_Scan =  0
FEUSB_GetScanListSize =  1
Traceback (most recent call last):

  File "C:\xxxxx\3.1_ObidRFID_test\OBID_RFID_06.py", line 265, in <module>
    data = RFID.FEUSB_GetScanListPara(i, b"Device-ID")

  File "C:\xxxxx\3.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

工作代码

代码语言:javascript
复制
    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)
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-09-28 20:31:38

您的.argtypes声明将与C原型相匹配:

代码语言:javascript
复制
int FEUSB_GetScanListPara(int, wchar_t*, char**)

您还没有提供确切的C原型,但是从您的示例:

代码语言:javascript
复制
FEUSB_GetScanListPara( 0, "Device-ID", sDeviceSerialNumber ) ;

而且知道wchar_t*不是公共接口参数,您可能实际上有简单的char*声明,如:

代码语言:javascript
复制
int FEUSB_GetScanListPara(int, const char*, char*);

假设第二个参数是输入参数,第三个参数是输出参数。请注意,c_char_p对应于一个字节字符串,因此对cPara使用b'DeviceID'。此外,如果您必须分配缓冲区,则第三个参数不太可能为char**。如果应用程序接口本身没有返回指针,而是填充了一个已经分配的缓冲区,则char*ctypes.c_char_p是合适的。您正确地使用了create_string_buffer()作为输出参数。

注您不需要将iIndex包装在c_int中。从.argtypes中,ctypes知道第一个参数是一个c_int,并为您转换它。如果没有提供.argtypes,这也是默认设置,但最好是显式地提供.argtypes

这段代码应该可以工作。我没有DLL来验证:

代码语言:javascript
复制
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原型。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/69367865

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档