Java JNI GetFieldID为内部类返回null

Java JNI GetFieldID为内部类返回null,java,android,java-native-interface,jnienv,Java,Android,Java Native Interface,Jnienv,我想在JNI中访问公共内部类。访问内部类的fieldId时GetFieldID返回null 下面是代码 public class classA{ public class classB{ public int b1; } public int a1; public classB B; } 注意:当我在类文件上运行javap-s时,我得到了以下输出 public class level1.level2.level3.classA{ public int a1;

我想在JNI中访问公共内部类。访问内部类的fieldId时GetFieldID返回null

下面是代码

public class classA{
    public class classB{
    public int b1;
    }
   public int a1;
   public classB B;
}
注意:当我在类文件上运行javap-s时,我得到了以下输出

public class level1.level2.level3.classA{
public int a1;
    descriptor : I
public level1.level2.level3.classA$classB B;
    descriptor : Llevel1/level2/level3/classA$classB;
下面是调用本机函数的类

public class extraclass{
    private native int myfunction1(classA A);
    public int extrafunction(classA A){
        myfunction1(A);
    }
}
本机代码

JNIEXPORT jint JNICALL myfunction1( JNIEnv *env, jobject obj ,jobject A)
{
    jclass cls = (*env)->GetObjectClass( env, A);
    jfieldID ja1,jB;
    int a1;

    ja1 = (*env)->GetFieldID( env, cls, "a1","I" );
    a1  = (*env)->GetIntField(env, config, ja1); // This works good.

    jB = (*env)->GetFieldID( env, cls, "B","Llevel1/level2/level3/classA$classB;" ); 
    // <<< Its crashing here with "JNI DETECTED ERROR IN APPLICATION: JNI GetFieldID called with pending exception 'java.lang.NoSuchFieldError'"

}

有人能建议如何获取classB的字段id并访问b1吗

这本书很老了,但也许有人会发现它很有用

在您的例子中,包和字段的名称内部看起来有点“混乱”

它可以很好地与以下代码配合使用:

.
|-- Makefile
|-- README.md
|-- c
|   `-- level1_level2_level3_extraclass.c
|-- java
|   `-- level1
|       `-- level2
|           `-- level3
|               |-- classA.java
|               `-- extraclass.java
|-- lib
`-- target
其中
classA.java
包含

package level1.level2.level3;

public class classA {

  public class classB {
    public int b1 = 42;
  }

  public int a1 = 44;
  public classB B = new classB();

}
extraclass.java
的形式如下:

package level1.level2.level3;

import level1.level2.level3.classA;

public class extraclass {

    static {

      System.loadLibrary("Extra");
    }

    private native int myfunction1(classA A);

    public int extrafunction(classA A){
        return myfunction1(A);
    }

    public static void main(String [] arg) {

      extraclass ex = new extraclass();
      classA a = new classA();

      System.out.println("Result: " + ex.extrafunction(a));
    }
}
当涉及到
C
code时,它与您提供的略有不同

#include <jni.h>

JNIEXPORT jint JNICALL Java_level1_level2_level3_extraclass_myfunction1( JNIEnv *env, jobject obj, jobject objA)
{
    jclass cls = (*env) -> GetObjectClass( env, objA );

    jfieldID fid_a1   = (*env) -> GetFieldID( env, cls, "a1", "I" );
    int valA          = (*env) -> GetIntField( env, objA, fid_a1);

    jfieldID fid_B     = (*env) -> GetFieldID( env, cls, "B", "Llevel1/level2/level3/classA$classB;");
    jobject B_Val      = (*env) -> GetObjectField( env, objA, fid_B );

    jclass clsClassB   = (*env) -> GetObjectClass( env, B_Val );

    jfieldID fid_b1    = (*env) -> GetFieldID( env, clsClassB, "b1", "I" );
    int valB           = (*env) -> GetIntField( env, B_Val, fid_b1 );

    return valB + valA;

}
#包括
JNIEXPORT jint JNICALL Java_level1_level2_level3_extraclass_myfunction1(JNIEnv*env、jobject obj、jobject objA)
{
jclass cls=(*env)->GetObjectClass(env,objA);
jfieldID fid_a1=(*env)->GetFieldID(env,cls,“a1”,“I”);
int valA=(*env)->GetIntField(env、objA、fid_a1);
jfieldID fid_B=(*env)->GetFieldID(env,cls,“B”,“Llevel1/level2/level3/classA$classB;”;
jobject B_Val=(*env)->GetObjectField(env、objA、fid_B);
jclass clsClassB=(*env)->GetObjectClass(env,B_Val);
jfieldID fid_b1=(*env)->GetFieldID(env,clsClassB,“b1”,“I”);
int-valB=(*env)->GetIntField(env,B_-Val,fid_-b1);
返回valB+valA;
}
无论如何,只要稍微清理一下代码,并确保所有包名都已就位,一切都会按预期进行


您可以在这里找到提炼版本:

您提供的消息说您正在调用某个东西,而之前的
GetFieldID()
调用仍然存在挂起的异常。如果它发生在第二个
GetFieldID()
调用上,那么它一定是第一个失败的调用。什么是
config
#include <jni.h>

JNIEXPORT jint JNICALL Java_level1_level2_level3_extraclass_myfunction1( JNIEnv *env, jobject obj, jobject objA)
{
    jclass cls = (*env) -> GetObjectClass( env, objA );

    jfieldID fid_a1   = (*env) -> GetFieldID( env, cls, "a1", "I" );
    int valA          = (*env) -> GetIntField( env, objA, fid_a1);

    jfieldID fid_B     = (*env) -> GetFieldID( env, cls, "B", "Llevel1/level2/level3/classA$classB;");
    jobject B_Val      = (*env) -> GetObjectField( env, objA, fid_B );

    jclass clsClassB   = (*env) -> GetObjectClass( env, B_Val );

    jfieldID fid_b1    = (*env) -> GetFieldID( env, clsClassB, "b1", "I" );
    int valB           = (*env) -> GetIntField( env, B_Val, fid_b1 );

    return valB + valA;

}