从Java中的JNI设置值:JNI java.lang.NoSuchFieldError

时间:2014-11-11 10:23:45

标签: java android c android-ndk java-native-interface

我试图从 JNI 设置变量的值( java 中的变量)。
我使用GetFieldIDSetIntField来做同样的事情。

以下是我的代码。

的main.c

JNIEXPORT void JNICALL Java_com_example_hello_MainActivity_samplefunc
(JNIEnv *env, jobject obj, jobject x)
{

    jclass class = (*env)->GetObjectClass(env, x);
    jfieldID fid = (*env)->GetFieldID(env, myclass,"a","I");
    (*env)->SetIntField(env, obj ,fid, 10);

    return;
}

MainActivity.java

 package com.example.hello;
 public class MainActivity extends ActionBarActivity 
 {
    int a = -1;

    /* Declaration of Native function &  Load JNI Library*/
    public static native void samplefunc(Class x);
    static {
        System.loadLibrary("hellojni");
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Class x = this.getClass();
        Log.d("JNI", "Before : Value of Port: " + a);
        samplefunc(x);
        Log.d("JNI", "After  : Value of Port: " + a);
        return;
    }
 }

预期的Logcat输出是:

D/JNI Before : Value of Port: -1
D/JNI After  : Value of Port: 10

但我收到以下错误:

D/JNI     (12607): Before : Value of Port: -1
W/dalvikvm(12607): JNI WARNING: JNI function SetIntField called with exception pending
W/dalvikvm(12607):              in Lcom/example/hello/MainActivity;.samplefunc:(Ljava/lang/Class;)V (SetIntField)
W/dalvikvm(12607): Pending exception is:
I/dalvikvm(12607): java.lang.NoSuchFieldError: no field with name='a' signature='I' in class Ljava/lang/Class;
I/dalvikvm(12607):  at com.example.hello.MainActivity.samplefunc(Native Method)

我想这有点基本,但我是JNI的新手 对此的任何帮助将不胜感激。

我已经看到了这个: JNI: NoSuchFieldError但是它并没有解释如何设置任何变量的值。

1 个答案:

答案 0 :(得分:1)

I/dalvikvm(12607): java.lang.NoSuchFieldError: no field with name='a' signature='I' in class Ljava/lang/Class;

此行告诉您,它正在班级Class中找到带有签名“我”的字段“a”而不是您的班级MainActivity。问题如下:

// 'x' is of type Class, since you called samplefunc(Class x)
// Therefore 'class' is set to Class and not MainActivity
jclass class = (*env)->GetObjectClass(env, x); 

// Here you try to access the field 'a' from class Class and not from your MainActivity. 
// Hence your error.
jfieldID fid = (*env)->GetFieldID(env, class,"a","I"); 

编辑:

一个简单的解决方案是将samplefunc更改为

samplefunc(MainActivity x)

然后您可以使用相同的代码,并按照Rolfツ

的建议获得正确的类