访问类JNI中的类数组中的变量

时间:2017-04-03 13:45:51

标签: android c java-native-interface

您好我有一个JNI问题,我有以下课程。我在用户空间的UserConfig类中设置变量a,b,c和d。

public class SetConfig extends Config {
    int status;

    public native int setConfig_IOCTL();

}

public class Config {
    public Config() { User = new UserConfig[100]; }

    int number;

    UserConfig[] user;
}

public class UserConfig {
    int a;
    int b;
    int c;
    int d;
}

然后我想将变量分配给一个c结构,然后传递给内核驱动程序。

typedef struct {
     int status;
     Config_t config;
} getConfig;

typedef struct {
    int number;
    UserConfig_t userConfig[100];
} Config_t;

typedef struct {
    int a;
    int b;
    int c;
    int d;
} UserConfig_t;

我在使用fieldId正确访问UserConfig类中的字段时遇到了问题,并且正在寻找一些帮助以指出我正确的方向。

我知道这是错误的。

JNIEXPORT jint JNICALL com_example_test_Config_config_IOCTL(JNIEnv *env, jobject instance) {

     getConfig_t tempConfig;   

     jclass thisClass = (*env)->GetObjectClass(env, instance);
     jfieldID fid = (*env)->GetFieldID(env, thisClass, "a", "[LTest/jni/UserConfig;");
     tempConfig.config.userConfig[0] = (*env)->GetIntField(instance, fid);

} 

任何帮助都会非常感激,因为我刚开始使用JNI。

1 个答案:

答案 0 :(得分:2)

C函数的名称将其与方法com.example.test.Config.config_IOCTL()相关联,但您的实际原生方法是<some_package>.SetConfig.setConfig_IOCTL()。类名和方法名都不匹配。您可以使用javah实用程序生成与Java类中的本机方法声明相对应的适当C声明。

将C函数声明与Java本机方法声明正确匹配后,您将需要本机方法(如目前声明的那样)来执行以下操作:

  • 获取调用该方法的对象的jclass,就像您已经做的那样。
  • 检索与该对象的jobjectarray字段相对应的userUserConfig[]
  • 通过GetObjectArrayElement()
  • 检索数组中所需的元素(?)
  • 找到该对象 s'类
  • 所需字段的fieldIds
  • 使用这些fieldID来检索字段的值

总的来说,这非常混乱。通常可以更好地在Java端执行,以使JNI端更容易编写。例如,你可能会做一些这样的事情(推断一下所需的语义):

public class SetConfig extends Config {
    int status;

    public int setConfig_IOCTL() {
        return setConfig_IOCTL(user[number].a, user[number].b, user[number].c,
                user[number].d);
    }

    private native int setConfig_IOCTL(int a, int b, int c, int d);
}

我确信您可以看到如何最大限度地减少本机方法实现的工作,并最大限度地减少需要调用的JNI函数的数量(可能为零)。当然,相应的本机实现将具有与您现有实现不同的签名。