在Python for .NET中如何传递FTDI.FT_DEVICE_INFO_NODE[]类型参数
解决Python for .NET调用FTD2XX_NET的GetDeviceList方法问题
我来帮你搞定这个调用问题——你遇到的核心问题是没遵循FTD2XX库的标准流程,也没掌握pythonnet处理.NET数组和ref参数的正确方式。先拆解下你的代码里的问题:
- 你创建了单个
FT_DEVICE_INFO_NODE对象,而不是数组,但GetDeviceList需要的是FT_DEVICE_INFO_NODE[]类型的参数; - 调用
GetDeviceList时用了静态方法FTDI.GetDeviceList,但实际上这是个实例方法,应该用你已经创建的ftdi对象来调用; - 你跳过了关键步骤:先获取设备数量,再创建对应长度的数组。
正确的实现步骤
对应你给出的C#代码,我们可以把它转换成Python版本,核心是处理ref参数和.NET数组:
- 获取设备数量:调用
GetNumberOfDevices,它需要一个ref UInt32参数,在pythonnet中我们可以直接传递System.UInt32的实例,库会自动处理引用传递; - 创建.NET强类型数组:如果设备数量大于0,用
System.Array.CreateInstance创建指定长度的FT_DEVICE_INFO_NODE数组(不能用Python原生列表,必须是.NET的强类型数组); - 调用GetDeviceList:把创建好的数组传入实例方法
ftdi.GetDeviceList; - 遍历设备列表:数组里的每个元素就是一个
FT_DEVICE_INFO_NODE对象,可以直接访问它的属性。
完整的修正代码
import clr import sys sys.path.append(r"C:\Users\[...]\FTD2XX_NET_v1.1.0\") # 注意用原始字符串避免转义问题 clr.AddReference("System") clr.AddReference("FTD2XX_NET") from FTD2XX_NET import FTDI from System import UInt32, Array ftdi = FTDI() if __name__ == '__main__': # 测试获取库版本(你的原有代码,正常运行) version_ = UInt32(0) ft_status, version = ftdi.GetLibraryVersion(version_) print(f'status: {ft_status}\nversion: {version}') # 获取设备数量 device_count = UInt32(0) ft_status = ftdi.GetNumberOfDevices(device_count) if ft_status != FTDI.FT_STATUS.FT_OK: print("Failed to get device count") sys.exit(1) print(f"Found {device_count} devices") # 获取设备列表 if device_count > 0: # 创建.NET强类型数组 device_list = Array.CreateInstance(FTDI.FT_DEVICE_INFO_NODE, int(device_count)) ft_status = ftdi.GetDeviceList(device_list) if ft_status == FTDI.FT_STATUS.FT_OK: # 遍历设备列表,打印每个设备信息 for idx in range(int(device_count)): dev_info = device_list[idx] print(f"\nDevice {idx+1}:") print(f"Flags: {dev_info.Flags}") print(f"Type: {dev_info.Type}") print(f"ID: {dev_info.ID}") print(f"LocId: {dev_info.LocId}") print(f"SerialNumber: {dev_info.SerialNumber}") print(f"Description: {dev_info.Description}") else: print("Failed to get device list") else: print("No devices found")
关键要点解释
- .NET数组 vs Python列表:pythonnet不能直接把Python列表传给需要.NET数组的方法,必须用
Array.CreateInstance创建对应类型的强类型数组; - ref参数处理:对于.NET的
ref值类型参数(比如UInt32),直接传递System.UInt32的实例即可,pythonnet会自动处理引用传递,方法调用后该实例的值会被更新; - 实例方法 vs 静态方法:
GetDeviceList是实例方法,必须用你初始化的ftdi对象调用,而不是直接调用FTDI.GetDeviceList; - 路径转义:在Python中路径字符串最好用原始字符串(前缀
r),避免反斜杠转义问题。
这样修改后,应该就能正确获取设备列表了。
内容的提问来源于stack exchange,提问作者mdk
相关产品推荐
相关产品推荐

