原始类型的 JNI GetObjectClass
JNI GetObjectClass with primitive type
我有以下 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);
只要 field 是引用类型(java.lang.Object 和子类型),此代码就可以工作。如果 field 是原始类型,当它试图执行 GetObjectClass.
时,它会导致 JVM 崩溃
我的问题是:如何使用 field 和 fieldValue 来判断它是否是原始类型以及它是否是原始类型类型,哪一个(整型、长整型、布尔型等)?
我是 JNI/JVMTI 的新手,所以如果答案很明显,请耐心等待。
谢谢!
用非对象类型的 jfieldID
调用 GetObjectField
是非法的。对于原始字段,您需要调用其他 Get[Type]Field
函数之一,其中 [Type]
是 Int
/Long
/Boolean
/etc.
因为你已经有了jvmti_env
,找到jfieldID
类型最简单的方法是调用JVM TI GetFieldName函数。除其他事项外,它 returns 字段签名,即字段类型。
唯一的问题是 jfieldID
应该总是伴随着 jclass
- 字段的持有者,因为字段 ID 是相对于特定的 class。通常,当您获得 jfieldID
时,您已经知道它的持有者 class。如果不是,在您的情况下,您有 jObjectInstance
- 一个具有此字段的对象,因此持有人 class 可以使用 JNI GetObjectClass 函数从实例派生。
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);
}
我有以下 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);
只要 field 是引用类型(java.lang.Object 和子类型),此代码就可以工作。如果 field 是原始类型,当它试图执行 GetObjectClass.
时,它会导致 JVM 崩溃我的问题是:如何使用 field 和 fieldValue 来判断它是否是原始类型以及它是否是原始类型类型,哪一个(整型、长整型、布尔型等)?
我是 JNI/JVMTI 的新手,所以如果答案很明显,请耐心等待。
谢谢!
用非对象类型的 jfieldID
调用 GetObjectField
是非法的。对于原始字段,您需要调用其他 Get[Type]Field
函数之一,其中 [Type]
是 Int
/Long
/Boolean
/etc.
因为你已经有了jvmti_env
,找到jfieldID
类型最简单的方法是调用JVM TI GetFieldName函数。除其他事项外,它 returns 字段签名,即字段类型。
唯一的问题是 jfieldID
应该总是伴随着 jclass
- 字段的持有者,因为字段 ID 是相对于特定的 class。通常,当您获得 jfieldID
时,您已经知道它的持有者 class。如果不是,在您的情况下,您有 jObjectInstance
- 一个具有此字段的对象,因此持有人 class 可以使用 JNI GetObjectClass 函数从实例派生。
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);
}