Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/325.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 GetObjectClass_Java_Jvm_Java Native Interface_Jvmti - Fatal编程技术网

Java 具有基元类型的JNI GetObjectClass

Java 具有基元类型的JNI GetObjectClass,java,jvm,java-native-interface,jvmti,Java,Jvm,Java Native Interface,Jvmti,我有以下JNI/JVMTI代码: jfieldID field = ...; jobject fieldValue = (*jni_env)->GetObjectField(jni_env, jObjectInstance, field); jclass fieldClass = (*jni_env)->GetObjectClass(jni_env, fieldValue); char* signature_ptr; char* generic_ptr; (*jvmti_env)-&

我有以下JNI/JVMTI代码:

jfieldID field = ...;
jobject fieldValue = (*jni_env)->GetObjectField(jni_env, jObjectInstance, field);
jclass fieldClass = (*jni_env)->GetObjectClass(jni_env, fieldValue);
char* signature_ptr;
char* generic_ptr;
(*jvmti_env)->GetClassSignature(jvmti_env, fieldClass, &signature_ptr, &generic_ptr);
当long字段是引用类型(java.lang.Object和子类型)时,此代码就可以工作。如果字段是基元类型,则当它尝试执行GetObjectClass时,会使JVM崩溃

我的问题是:如何使用field和fieldValue来判断它是否是一个基本类型,以及它是否是一个基本类型(int、long、boolean等)

我是JNI/JVMTI的新手,所以如果答案很明显,请容忍我


谢谢

使用非对象类型的
jfieldID
调用
GetObjectField
是非法的。对于基本字段,您需要调用另一个
Get[Type]Field
函数,其中
[Type]
Int
/
Long
/
Boolean
/等

由于您已经有了
jvmti_env
,因此查找
jfieldID
类型的最简单方法是调用jvmti函数。除其他外,它返回字段签名,即字段的类型

唯一的问题是
jfieldID
应该始终伴随
jclass
——字段的持有者,因为字段id是相对于特定类的。通常,当您获得
jfieldID
时,您已经知道它的holder类。如果没有,那么在您的示例中,您有一个具有此字段的对象
jObjectInstance
,因此可以使用JNI函数从实例派生holder类

jclass fieldHolder = (*jni_env)->GetObjectClass(jni_env, jObjectInstance);

char* name;
char* signature;
if ((*jvmti_env)->GetFieldName(jvmti_env, fieldHolder, field, &name, &signature, NULL) == 0) {

    switch (signature[0]) {
        case 'I':
            // int
            break;
        case 'J':
            // long
            break;
        ...
        case 'L':
            // object
            break;
        case '[':
            // array
            break;
    }

    (*jvmti_env)->Deallocate(jvmti_env, signature);
    (*jvmti_env)->Deallocate(jvmti_env, name);
}

您是如何获得jfieldID字段的?JNI
GetFieldID
函数需要字段名和签名,因此通常在获取
jfieldID
时,您已经知道字段的类型。JVMTI GetClassFields中有一个方法可以返回JCClass的所有字段。谢谢!我看到并尝试使用GetFieldName,但我误解了jclass参数的文档,该参数表示要查询的字段的类。我认为是jfieldID的类,而不是包含该字段的实例的类。