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 關注
- 399 瀏覽
添加回答
舉報