使用JNA的USBFS IOCTL调用不适用于64位体系结构

moictab:

在Android中,我使用类(UsbIso.java)从连接的USB设备以同步方式传输数据。由于Android本机不支持同步传输,因此我不得不通过JNA库使用USBFS本机Linux机制进行正确的ioctl调用。

在具有32位架构的Android设备(armeabi,armeabi-v7a)中,所有功能均可正常运行。在具有64位体系结构(arm64-v8a)的Android设备中,要获取URB的ioctl调用(reapRequest方法内部的USBDEVFS_REAPURB,请参见下面的相关代码)将返回错误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; 
            }
        }
...

}
丹尼尔·威迪斯(Daniel Widdis):

您正在使用针对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字节,因此setUserContext()getUserContext()需要处理long而不是int,并且urbBaseSize需求从44增加到52(+为buffer4,对于+为4 userContext

我看到一些其他int变量表示需要变为longs的内存地址我可能还需要其他更改。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

为什么自调用不适用于Spring代理(例如,使用AOP)?

使用每个函数的Ajax调用不适用于多个div

您如何使用Java确定Windows的32位或64位体系结构?

如何使用Ant确定构建体系结构(32位/ 64位)?

R正在使用mingw_32来编译64位体系结构的软件包

在64位Debian Wheezy多体系结构主机上编译使用ssl的32位二进制文件

导航体系结构组件:过渡动画不适用于对话框

如何使用 JNA 调用 setProcessMitigationPolicy

使用./configure生成.dylib或.a文件以用于特定体系结构

使用this.props时,禁用不适用于复选框

将ReactRouter与Router一起使用不适用于React Hook

应用不适用于使用 Apache Beam 的 ParDo 和 DoFn

相同的程序适用于 C,但不适用于 C++(使用 linux 系统调用)

我应该使用Int32代替64位体系结构中的Int还是Int64来实现较小数量

使用ArrayAdapter不适用于片段

使用JNA访问包含载体的结构<字符*>

使用JNA定义的字段加载的结构错误

使用JNA并行调用不可重入的本机函数

Rest API调用可与curl配合使用,但不适用于PowerShell

ng-hide / ng-show 不适用于使用 ng-click 调用的函数

不适用于使用注释的翻新拦截器的OkHttp调用超时

干净的体系结构:对不同的数据源使用不同的模型类?

使用JNA调用Gdi32.GetObject

是由jvm限制的C代码在JNA(或JNI)中分配的内存(参数-Xmx或体系结构32/64)

如何使用NDK 19在OSX Darwin上交叉编译适用于64位Android的OpenSSL

JNA 在 Linux 上使用 64 位 libmx.so 崩溃

`cdll.LoadLibrary("my.so")` 抛出“找不到合适的图像”。但是体系结构匹配,并且两者都适用于 64 位。为什么?

ajax调用不适用于c#方法

Ajax调用不适用于laravel项目