【问题标题】:Bad type conversion in android ndkandroid ndk中的错误类型转换
【发布时间】:2014-12-09 22:19:32
【问题描述】:

我希望我的 Android 应用程序创建一个假的虚拟设备,要实现这一点,设备需要 root 并且需要 uinput 模块。

我正在使用以下代码创建设备,调用

static{ System.loadLibrary("myModule"); }
CreateVirtualDevice("Devname",0x123,0x123);

在我的 java 代码中。 这里是原生代码:

#include <string.h>
#include <jni.h>
#include <fcntl.h>

#include <linux/input.h>
#include <linux/uinput.h>

static int fd;
static struct uinput_user_dev dev;

short int analog_axis_list[] = { ABS_X,ABS_Y,ABS_RX,ABS_RY, -1};

jint Java_com_example_app_MyClass_CreateVirtualDevice(
        JNIEnv* env, jobject thiz, jstring param, jint param2, jint param3) {

    int i;

    memset(&dev, 0, sizeof(dev));
    fd = open("/dev/uinput", O_WRONLY | O_NONBLOCK);
    if (fd < 0)
        return -1;
    if(ioctl(fd, UI_SET_EVBIT, EV_ABS)<0) return -4;


    for(i=0;analog_axis_list[i]>=0;i++){
        if(ioctl(fd,UI_SET_ABSBIT,analog_axis_list[i])<0) return -5;
        dev.absmax[analog_axis_list[i]]=32767;
        dev.absmin[analog_axis_list[i]]=-32768;
    }

    const char *cparam = (*env)->GetStringUTFChars(env, param, 0);
    snprintf(dev.name, UINPUT_MAX_NAME_SIZE, cparam);
    (*env)->ReleaseStringUTFChars(env, param, cparam);
    dev.id.bustype = BUS_VIRTUAL;
    dev.id.vendor = param2;
    dev.id.product = param3;
    dev.id.version = 1;

    if (write(fd, &dev, sizeof(dev)) < 0)
        return -7;

    if (ioctl(fd, UI_DEV_CREATE) < 0)
        return -8;
    return 0;

}

设备创建成功,返回值为0。 在input.h 内部,ABS 的值是这样定义的:

#define ABS_X  0x00
#define ABS_Y  0x01
#define ABS_RX 0x03
#define ABS_RY 0x04

但是当检查 android 上的轴时,我得到了正确的 AXIS_X 和 AXIS_Y 值,但是 ABS_RX 和 ABS_RY 的值错误。我使用此代码检查轴值:

InputDevice device = InputDevice.getDevice(ids[position]);
List<InputDevice.MotionRange> ranges = device.getMotionRanges();
StringBuilder sb = new StringBuilder("");
if(ranges.size()==0){
    sb.append("NO_MOTION_RANGES");
}
else{
    int i = 0;
    for(InputDevice.MotionRange range:ranges) {
        if(i>0) {
            sb.append(",");
        }
        sb.append(MotionEvent.axisToString(range.getAxis()));
        sb.append("(").append(range.getAxis()).append(")");
        i++;
    }
}
return sb.toString();

结果是:

AXIS_X(0),AXIS_Y(1),AXIS_Z(11),AXIS_RZ(14)

我使用的是最新的 NDK 版本 (r10d),没有启用任何特定设置。什么会导致这些错误?

我想指出我的代码有问题,因为使用实际控制器时轴号是正确的。

编辑 1: 我试图在我的函数结束时返回analog_axis_list[2],而不是0,它返回3,它是ABS_RX,所以我认为我将错误的类型传递给ioctl 调用。 我应该选择哪种类型?

【问题讨论】:

  • ioctl() 是原型:int ioctl(int d, unsigned long request, ...);。但是您没有利用在大多数(如果不是全部)代码 sn-p 中查看返回值的优势。尝试确保值(参数)正确注册。
  • @ryyker 我添加了对所有 ioctl 调用的检查,函数返回 0。

标签: android c android-ndk uinput


【解决方案1】:

Android 使用 AXIS_Z 和 AXIS_RZ 作为右摇杆;这与 USB HID 一致。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-10-21
    • 2018-05-05
    • 2013-04-01
    • 2018-12-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多