2017-04-03 16 views
0

現在、ヒープメモリからフィールド値をコピーできるように、JNIを使​​用してメモリ内のフィールドのオフセットを取得しようとしています。フィールドのjFieldIDを使用してインスタンスフィールドのオフセットを取得できました。 jFieldIDの最上位30ビットは、インスタンスフィールドのフィールドのオフセットを表します。問題は静的フィールドにあります。 30ビットはJNIid *を表します。 JNIidは、おそらくフィールドのオフセットであるintオフセットフィールドを含む構造体です。今私の問題は、この価値をどうやって得るのかということです。私は、これはしかし、私は任意の値を与えていない静的フィールドのJNIフィールドID

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; 

(IDフィールドのjfieldIDであり、address_shiftが2であると仮定して)次のコードスニペットを使用しました。私はそれが私がUnsafe.staticFieldOffset(Field)から得たものと比較しているので、正しいものではない0を得る。私はJNIからこのメソッドを呼び出して結果を使用できることを知っています。しかし、私はそれがパフォーマンス重視のアプリケーションのために必要です。

+5

を実行JNIは、フィールドの値を読み取るための機能を提供します。特定のJNI実装をリバースエンジニアリングするのではなく、これらを使用することを強くお勧めします。 –

+0

はい、私は知っていますが、フィールド値を1つずつコピーしたくありません。だから私は最小のオフセットと最大値を取得し、コピーメモリをしたいと思います。 –

+0

@MohamedOmerなぜメモリ内のオフセットが変わらないと思いますか? –

答えて

1

多分あなたは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 
+0

BTW - ここでもっとJNIサンプルを見つけることができます:http://jnicookbook.owsiak.org/ – mko

+0

はい、私はJNIを使​​って値を取得できます。しかし、私はメモリから値をコピーしたいと思います。クラスに10個の静的フィールドがあるとします。私はループでそれらをコピーしたくありません。 minオフセットとmaxオフセットを取得し、minから(max + size)までの値をコピーするunsafe.copememoryを実行したいと思います。 –

関連する問題