3

私が行っていることは次のとおりであることを十分に認識しています:
1)安全ではない、安全性を入力JVMできないため、クラッシュする可能性がある
2)ByteBuffersを使用して同様の操作を実行できる、またはJNI
3)安全でないことが内部クラスである消える可能性があります。

私はこれを実験目的でのみ行っており、その結果を認識しています。

これを念頭に置いて、Unsafeとreflectionを使用して配列からデータを抽出しようとしています。

最初に、配列のフィールドオフセットを見つけます。

public long findFieldOffset(Event event) {
    try {
        Class cl = event.getClass();            
        Field data_field = cl.getDeclaredField("data");            
        data_field.setAccessible(true);
        long offset = unsafe.objectFieldOffset(data_field);            
        return offset;            
    } catch (NoSuchFieldException e) {
        e.printStackTrace();
    }
    return 0;        
}

また、配列の基本位置を抽出します。

       int base = unsafe.arrayBaseOffset(byte[].class);

その後、Eventクラスから配列を抽出し、それをバッファーにコピーしようとします(byte_offsetの結果ですfindFieldOffset)。
以下のコードでは、最初の部分は単なるテスト関数であり、正しい文字列を出力します。2番目の部分は配列となるはずのものを抽出しますが、テストするとガベージユニコード値が返されます。

                  /* Testing  */
                    active_buffer.getBuffer().position(1); 
                    active_buffer.getBuffer().put(event.getData()); 
                    active_buffer.getBuffer().position(1); 
                    active_buffer.getBuffer().get(tuple, 0, (int)tuple_size);
                    System.out.println("Test1: " + new String(tuple)) ;
                   /* Test1 prints out the correct string */

                    unsafe.copyMemory( (Object) event,  byte_offset  +  base, (Object) null, active_buffer.getAddress() + 1, tuple_size);
                    active_buffer.getBuffer().position(1); 
                    active_buffer.getBuffer().get(tuple, 0, (int)tuple_size);
                    System.out.println("Test2: " + new String(tuple)); 
                    /* Garbage unicode values gets printed*/ 

誰かがこのコードに何か問題があるのを見ることができますか?

4

1 に答える 1

2

フィールドと同様dataに、それはプリミティブまたは参照のいずれかです。どちらの場合も、どこかにコピーして、フィールドとして扱うことはできません。byte[]

がbyte[]の場合data、これをイベントではなく真のオブジェクトとして扱う必要があります。

于 2012-09-06T14:46:58.260 に答える