静态字段的JNI字段ID

时间:2017-04-03 13:28:58

标签: java c java-native-interface

我目前正在尝试使用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调用这个方法并使用结果。但我希望它能用于性能关键的应用程序。

1 个答案:

答案 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