我目前正在尝试使用JNI获取内存中的字段的偏移量,以便能够将字段值复制到关闭堆内存。我能够使用字段的jFieldID获取实例字段的偏移量。 jFieldID的最重要的30位表示实例字段的字段的偏移量。问题出在静态字段上。 30位代表JNIid *。 JNIid是一个包含int偏移字段的结构,该字段可能是字段的偏移量。现在我的问题是如何获得这个值。我使用了以下代码片段(假设id是字段的jFieldID,address_shift是2)
uintptr_t result = (uintptr_t) id >> address_shift;
// offset field in JNIid struc is in offset 16
jlong staticFieldoffsetAddress = result + 16;
jint* staticFieldValuePointer = (jint*) staticFieldoffsetAddress;
然而,这并没有给我任何价值。我得到0这是不正确的,因为我将它与我从java中的Unsafe.staticFieldOffset(Field)得到的内容进行比较。我知道我可以从JNI调用这个方法并使用结果。但我希望它能用于性能关键的应用程序。
答案 0 :(得分:2)
也许你可以使用GetStaticFieldID方法?
public class Static {
private static int field;
private native void access();
public static void main(String args[]) {
Static s = new Static();
Static.field = 1;
s.access();
}
static {
System.loadLibrary("Static");
}
}
C源
#include "jni.h"
JNIEXPORT void JNICALL
Java_Static_access(JNIEnv *env, jobject obj)
{
jfieldID fieldId;
jint fieldValue;
jclass class = (*env)->GetObjectClass(env, obj);
fieldId = (*env)->GetStaticFieldID(env, class, "field", "I");
if (fieldId == NULL) {
return;
}
fieldValue = (*env)->GetStaticIntField(env, class, fieldId);
printf("Value: %d\n", fieldValue);
}
编译并运行
> javac Static.java
> javah -jni Static
> cc -g -shared -fpic -I${JAVA_HOME}/include \
-I${JAVA_HOME}/include/darwin \
static.c -o libStatic.dylib
> java Static
Value: 1