Visual Studio 更新后 FTD2XX 函数在 VB.NET 中不起作用的原因是什么(?),是否有可能修复?

What is the reason that FTD2XX functions do not work in VB.NET after Visual Studio update(?), is there possible fix?

我正在 VB.NET 中开发一个应用程序(针对硬件使用 FTDI USB 串行芯片的客户。通信使用 FTD2XX 库和相应的 Nuget 包(FTD2XX.Net v1.2.1)。经过一些Visual Studio 的更新(可能更新到 17.1,但我不确定)除了少数几个停止工作之外的所有功能。当前 VS 版本是 17.1.1。 例如,可以获取 FTDI 驱动程序连接的设备数:

Friend Declare Function FT_CreateDeviceInfoList Lib "FTD2XX.DLL" (ByRef lngNumDevs As Integer) As Integer
...
Dim ftStatus As Integer
Dim numDevices As Integer
ftStatus = FT_CreateDeviceInfoList(numDevices)

在上面的代码片段中,ftStatus 结果 = 0(即正常)并且 numDevices 设置为 1(正确)。

当我想做一些严肃的事情时,问题就开始了:

Friend Declare Function FT_GetComPortNumber Lib "FTD2XX.DLL" (ByVal lnghandle As Integer, ByRef lplComPortNumber As Integer) As Integer
Friend Declare Function FT_Open Lib "FTD2XX.DLL" (ByVal iDevice As Integer, ByRef lnghandle As Integer) As Integer
Friend Declare Function FT_Close Lib "FTD2XX.DLL" (ByVal lnghandle As Integer) As Integer
Dim portHandle as Integer
Dim cpNumber as Long
For i% = 0 To 255
   ftStatus = FT_Open(i, portHandle)
   If ftStatus = FT_OK Then
      ftStatus = FT_GetComPortNumber(portHandle, cpNumber)
      ftStatus = FT_Close(portHandle)
      ' here is some non-essential code registering that port at index i% exists...
   End If
Next

在上面的代码中,FT_Open returns ftStatus = 0 (FT_OK) 并为 portHandle.

设置了一个值

然而,接下来的调用,FT_GetComPortNumber,returns ftStatus = 1 (FT_INVALID_HANDLE) 并且传给cpNumber的值是0xFFFF(显示为正数,但实际上应该是 -1,我猜......)。更糟糕的是,FT_Close() 也 returns FT_INVALID_HANDLE 并且端口保持打开状态。我通过尝试从另一个应用程序打开端口来验证它 - 访问被拒绝。

有时似乎 FT_WriteFT_Read 函数尽管出现这种情况仍能正常工作,但在我最后一次尝试中我根本无法与硬件进行任何通信。

我尝试使用 System.IO.Ports.SerialPort 作为可能的解决方法,但这根本不起作用。最重要的是,我需要在 RTS 上使用 bit-bang,因为它控制电源电压和连接到 FTDI 芯片另一侧的硬件的复位。不可能将 RTS 降低数百毫秒,然后一直保持下去,我无法控制硬件。 AFAIK System.IO.Ports.SerialPort 无法做到这一点。

有什么解决办法?

经过反复试验,似乎是编译配置的问题。 打开解决方案属性 Window 并单击“编译”选项卡。

然后点击“高级编译选项”

如果“删除整数溢出检查”复选框未选中,请选中它!

我不知道整数溢出检查如何混淆一个不涉及任何算术运算的 32 位数字,但这就是真实发生的情况。我认为这是 Visual Studio 17.1.6(以及许多以前的版本)中使用的 Visual Basic 编译器中的一个错误,但我没有深入探讨这个主题。

@HansPassant 写道:

声明错误,必须是lnghandle As IntPtr。当您在 64 位模式下 运行 应用程序时,IntegerIntPtr 之间的区别很重要。以 .NETCore 为目标时很容易发生,就像在 VS2022 中一样。

-- 汉斯·帕桑特