Java JNI GetFieldID为内部类返回null
我想在JNI中访问公共内部类。访问内部类的fieldId时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;
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;
}