亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

USBFS IOCTL 調用 witn JNA 在 64 位架構中不起作用

USBFS IOCTL 調用 witn JNA 在 64 位架構中不起作用

冉冉說 2023-03-31 17:10:59
在 Android 中,我使用一個類 ( UsbIso.java ) 從連接的 USB 設備以同步方式傳輸數據。由于 Android 本身不支持同步傳輸,我不得不通過 JNA 庫使用 USBFS 原生 Linux 機制來進行正確的 ioctl 調用。在具有 32 位架構(armeabi、armeabi-v7a)的 Android 設備中,一切正常。在具有 64 位架構 (arm64-v8a) 的 Android 設備中,ioctl 調用 reap URB(USBDEVFS_REAPURB,在 reapRequest 方法內部,請參見下面的相關代碼)返回錯誤 14,地址錯誤。我猜這是由 USBDEVFS_REAPURB 參數或 PointerByReference 參數引起的,它指向一個無效的虛擬地址,但我不知道如何解決它。UsbIso.java類中導致該錯誤的相關代碼是這樣的:public Request reapRequest (boolean wait) throws IOException {        PointerByReference urbPointer = new PointerByReference();        int func = wait ? USBDEVFS_REAPURB : USBDEVFS_REAPURBNDELAY;        int rc;        try {            rc = libc.ioctl(fileDescriptor, func, urbPointer);  // <-- Error 14, bad address        } catch (LastErrorException e) {            if (e.getErrorCode() == EAGAIN && !wait) {                return null;             }        }...}
查看完整描述

1 回答

?
皈依舞

TA貢獻1851條經驗 獲得超3個贊

您正在使用針對 32 位優化的源代碼:


// Note: The layout and size of the USBFS structures matches that of Linux Kernel 3.2 and 3.14

// for ARM 32 bit. For other environments (X86, 64 bit, future Linux kernels), it might be

// necessary to adjust some values.

雖然 JNA 通常會針對 32 位和 64 位調整結構映射,但此代碼認為 JNA 太慢并手動映射這些偏移量:


// This class is modeled after struct usbdevfs_urb in <linuxKernel>/include/linux/usbdevice_fs.h

// At first I implemented the URB structure directly using com.sun.jna.Structure, but that was extremely slow.

// Therefore byte offsets are now used to access the fields of the structure.

如果您查看結構映射,usbdevfs_urb有 3 個指針字段需要從 4 字節偏移量調整為 8 字節偏移量。例如,第 5 個字段buffer從 4 個字節變為 8 個字節,因此此代碼中斷:


   public void setBuffer (Pointer buffer) {

      urbBuf.putInt(12, (int)Pointer.nativeValue(buffer)); }

   public void setBufferLength (int bufferLength) {

      urbBuf.putInt(16, bufferLength); }

特別是,putInt(12, (int) ...)可能應該是putLong(12, ...),下一次調用中的 16 應該是 20(依此類推,將 4 添加到剩余的偏移量中。)


最后兩個字段也是 8 字節 vs. 4 字節,所以 andsetUserContext()需要getUserContext()處理long而不是intandurbBaseSize需要從 44 遞增到 52(+4 為buffer,+4 為userContext.


我看到一些其他int變量代表需要變成longs 的內存地址。我可能錯過了其他需要的更改。


查看完整回答
反對 回復 2023-03-31
?
素胚勾勒不出你

TA貢獻1827條經驗 獲得超9個贊

正如 Peter Stoiber 在這個問題的最后一個答案中所述,存在一個解決這個問題的類:https ://github.com/Peter-St/Android-UVC-Camera/tree/master/app/src/main /java/humer/uvc_camera/UsbIso64


查看完整回答
反對 回復 2023-03-31
  • 1 回答
  • 0 關注
  • 300 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號