2 回答
TA贡献2039条经验 获得超8个赞
当句柄不是正确的 kernel32 句柄或句柄已关闭时,CloseHandle() 会失败。通过挖掘 github 源代码,我发现了问题的根源:
[DllImport("winusb.dll", SetLastError = true)]
public static extern bool WinUsb_Initialize(SafeFileHandle DeviceHandle,
out SafeFileHandle InterfaceHandle);
编辑以适应并使问题更加明显。第二个参数的类型不正确,该函数不返回 kernel32 句柄,因此将其包装在 SafeFileHandle 中是不正确的。这是一个不透明的句柄,本机 api 声明中的 WINUSB_INTERFACE_HANDLE,通常是引擎盖下的指针。只有一种正确的方法可以关闭它,您必须调用 WinUsb_Free()。代码这样做了,但调用 CloseHandle也是不正确的,注定会失败。SafeFileHandle 提供的 CloseHandle() 调用同样会失败,您可能还没有到那一步。
将参数类型更改为IntPtr. 这需要其他几处代码更改,主要是在 UsbInterface 类中。同样将其 Handle 属性类型更改为 IntPtr。删除其 Dispose() 方法中的 CloseHandle() 调用。编写您自己的 SafeHandle 派生类来包装它是另一种方式,然后您将重写 ReleaseHandle() 以调用 WinUsb_Free()。
TA贡献1772条经验 获得超5个赞
我认为这个问题的答案是没有必要在 USB 接口上调用 CloseHandle。根据本页顶部的 Dispose 方法,调用 WinUsb_Free 应该足以释放接口。只需调用 CloseHandle 即可释放 CreateFile 创建的设备的句柄。
public void Dispose()
{
if (_IsDisposed) return;
_IsDisposed = true;
var isSuccess = WinUsbApiCalls.WinUsb_Free(Handle);
WindowsDeviceBase.HandleError(isSuccess, "Interface could not be disposed");
}
这篇文章说得很清楚。
CloseHandle 释放由 CreateFile 创建的句柄,如步骤 1 中所述。
WinUsb_Free 释放设备的 WinUSB 接口句柄,由 WinUsb_Initialize 返回。
Hans Passant 还推荐:
在 Dispose() 方法中删除 CloseHandle() 调用
此外,来自汉斯·帕桑特:
第二个参数的类型不正确,该函数不返回 kernel32 句柄,因此将其包装在 SafeFileHandle 中是不正确的。这是一个不透明的句柄,本机 api 声明中的 WINUSB_INTERFACE_HANDLE,通常是引擎盖下的指针。只有一种正确的方法可以关闭它,您必须调用 WinUsb_Free()。
这并不直接涉及我所问的问题,但这是一个公平的观点。正如 Hans 指出的那样,我不能在 WinUsb_Initialize 返回的句柄上调用 Dispose() 的原因是这样做会在后台调用 CloseHandle,而 WinUsb_Initialize 返回的第二个参数不是 kernel32 句柄,所以 CloseHandle() 只是赢了'无论如何都行不通。这只是导致似乎没有任何迹象表明有必要在接口上调用 CloseHandle。所以,我相信我遇到的问题(单独的问题)与不调用 CloseHandle 无关。这似乎是固件本身的问题,制造商似乎已经确认了这一点。更多细节即将到来。
注意:如果我错了,请告诉我为什么我错了,并指出一个使用 CloseHandle 关闭 USB 接口上的句柄的示例。
- 2 回答
- 0 关注
- 506 浏览
添加回答
举报
