Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/360.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
从Java中的JNI设置值:JNI Java.lang.NoSuchFieldError_Java_Android_C_Android Ndk_Java Native Interface - Fatal编程技术网

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

从Java中的JNI设置值:JNI Java.lang.NoSuchFieldError,java,android,c,android-ndk,java-native-interface,Java,Android,C,Android Ndk,Java Native Interface,我正试图从JNI设置变量的值(java中的变量)。 我正在使用GetFieldID和SetIntField来做同样的事情 下面是我的代码 main.c JNIEXPORT void JNICALL Java_com_example_hello_MainActivity_samplefunc (JNIEnv *env, jobject obj, jobject x) { jclass class = (*env)->GetObjectClass(env, x); jfiel

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

下面是我的代码

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还是新手。
在此方面的任何帮助都将不胜感激

我已经看到了这一点: 但是,它没有解释如何设置任何变量的值

I/dalvikvm(12607): java.lang.NoSuchFieldError: no field with name='a' signature='I' in class Ljava/lang/Class;
此行告诉您,它正在类
class
中查找签名为“I”的字段“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建议的正确类ツ

另一个需要注意的事项是:我建议将本机方法更改为samplefunc(mainx);只需使用现有的代码。FindClass方法只能在您想要创建一个新的Java对象时使用。您确定此方法只能用于对象创建吗?最近没有使用JNI,也许你是对的。将方法更改为samplefunc(MainActivity x)可能更好。是的,因为当Java端创建了多个实例时,JNI如何知道该类的哪个实例。啊,你是对的,我想我把静态引用搞砸了。将改变这一点quickly@BluesSolo,在使用
MainActivity x=newmainActivity()时并调用
samplefunc(x)
I get
JNI警告:实例jfieldID 0x6d7aed24对类Ljava/lang/class无效;(SetIntField)W/dalvikvm(13829):在Lcom/example/hello/MainActivity;中;。samplefunc:(Lcom/example/hello/MainActivity;)V(SetIntField)
后跟
SIGABRT