【问题标题】:Using d2xx.dll in python with ctypes在带有 ctypes 的 python 中使用 d2xx.dll
【发布时间】:2020-02-14 01:42:37
【问题描述】:

我正在尝试使用 d2xx.dll,它是一个用于连接 FTDI 的 USB 控制器芯片的库。我想在我的 python 代码中使用这个库。我决定在 python 中使用 ctypes 库来调用 dll 函数。我未能从 dll 文件中适当地调用函数,并且我认为我在传递给 dll 库中的函数的变量类型方面存在一些问题。我不是专业程序员,所以请放轻松。 :D

这是迄今为止尝试过的,

import ctypes
from ctypes import *

d2xxdll = ctypes.cdll.LoadLibrary('ftd2xx.dll') #Load the dll library 
d2xxdll.FT_CreateDeviceInfoList.argtypes =[ctypes. c_ulong] # specify function's input type
d2xxdll.FT_CreateDeviceInfoList.restype = ctypes.c_ulong # specify function's return type

numDevs = ctypes.c_ulong()
p_numDevs = POINTER(numDevs)
FT_STATUS = d2xxdll.FT_CreateDeviceInfoList(p_numDevs)

print(FT_STATUS)
print(numDevs)

我只是想检测有多少 D2XX 设备与 FT_CreateDeviceInfoList() 函数连接。 FT_CreateDeviceInfoList 在d2xx.dll documentation 第 6 页中进行了描述。该函数有一个输入参数,它是一个指向无符号长整数的指针,它返回 USB 设备的状态。我用“numDevs = ctypes.c_ulong()”声明了一个无符号长整数,并在“p_numDevs = POINTER(numDevs)”中声明了它的指针,运行代码时出现以下错误。

Traceback (most recent call last):
  File "C:\Users\asus\Desktop\dokümanlar\Python_Ogren\Ctypes_cll\d2xx_dll.py", line 9, in <module>
    p_numDevs = ctypes.POINTER(numDevs)
TypeError: must be a ctypes type

我也试过用byref来传递numDevs的地址:

import ctypes
from ctypes import *

d2xxdll = ctypes.cdll.LoadLibrary('ftd2xx.dll') #Load the dll library 
d2xxdll.FT_CreateDeviceInfoList.argtypes =[ctypes. c_ulong] # specify function's input type
d2xxdll.FT_CreateDeviceInfoList.restype = ctypes.c_ulong # specify function's return type

numDevs = ctypes.c_ulong()

FT_STATUS = d2xxdll.FT_CreateDeviceInfoList(ctypes.byref(numDevs))

print(FT_STATUS)
print(numDevs)


这次我得到以下信息:

Traceback (most recent call last):
  File "C:\Users\asus\Desktop\dokümanlar\Python_Ogren\Ctypes_cll\d2xx_dll.py", line 10, in <module>
    FT_STATUS = d2xxdll.FT_CreateDeviceInfoList(ctypes.byref(numDevs))
ArgumentError: argument 1: <type 'exceptions.TypeError'>: wrong type

我应该如何传递输入参数?我知道python中有一些d2xx.dll的包装器,比如pyusb,但由于某种原因,我无法让它们工作。我用 d2xx.dll 编写了一些 C 代码,它们的工作方式非常有魅力。现在我正在寻找一种让他们在 python 中工作的方法。

提前致谢。

【问题讨论】:

    标签: python dll d2xx


    【解决方案1】:

    函数的C定义为:

    typedef ULONG   FT_STATUS;
    
    FTD2XX_API
    FT_STATUS WINAPI FT_CreateDeviceInfoList(
        LPDWORD lpdwNumDevs
    );
    

    ctypes 有一个 Windows 类型库,可帮助您正确映射它们。参数类型不是c_ulong,而是POINTER(c_ulong)wintypes 模块将LPDWORD 正确定义为这种类型。然后你创建一个DWORD 并将它传递给byref()

    下面是一个完整的包装器:

    import ctypes
    from ctypes import wintypes
    
    FT_STATUS = wintypes.ULONG
    FT_OK = 0
    
    # Note: WINAPI is __stdcall so if using 32-bit Windows you want WinDLL().
    #       Use CDLL() for __cdecl calling convention.
    #       On 64-bit Windows there is only one calling convention and either works.
    ftd2xx = ctypes.WinDLL('ftd2xx')
    
    _FT_CreateDeviceInfoList = ftd2xx.FT_CreateDeviceInfoList
    _FT_CreateDeviceInfoList.argtypes = wintypes.LPDWORD,
    _FT_CreateDeviceInfoList.restype = FT_STATUS
    
    def FT_CreateDeviceInfoList():
        num_devs = wintypes.DWORD()
        if _FT_CreateDeviceInfoList(ctypes.byref(num_devs)) != FT_OK:
            raise RuntimeError('failed')
        return num_devs.value
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-02-01
      • 1970-01-01
      • 2015-01-31
      • 1970-01-01
      • 2014-01-04
      • 1970-01-01
      相关资源
      最近更新 更多