2012-02-25 2 views
3

というタイトルでは、私はint []をJavaのByteBufferに変換する必要があります。これを行うための推奨される方法はありますか?int []をJavaのByteBufferに変換するには?

ByteBufferをJNIでC++に渡したいと思っています。この場合の特定のエンディアン変換については、何を考慮する必要がありますか?

編集:申し訳ありませんが、私は誤ってByteArrayを書きましたが、ByteBuffer型を意味していました。

編集:サンプルコード:

私は不要な部分を取り除きました。私はJNI上でC++からJava関数を呼び出してリソースをロードし、それをバイトバッファとしてC++に戻します。他のさまざまなリソースと連携して動作します。今、私は "int []"を持っていて、それをバイトバッファに変換するエレガントな方法があるかどうか、あるいはoldfashionedのやり方でforループを埋めなければならないかどうかを知りたいと思っています。

ByteBuffer resource= null; 
resource = ByteBuffer.allocateDirect((x*y+2)*4).order(ByteOrder.nativeOrder()); 
. 
. 
ByteBuffer GetResourcePNG(String text) 
{ 
    . 
    . 
    int [] pix; 
    map.getPixels(pix,0,x,0,0,x,y); 

    return resource; 
} 
+0

は、右のことですか?つまり、ByteBufferは抽象クラスです。あなたが必要とする正確なタイプは何ですか?いくつかのサンプルコードを提供してください。 –

答えて

5

JNI's GetDirectBufferAddressを使用するには、ByteBuffer.allocateDirectを使用する必要があります。

ByteBuffer.order(ByteOrder.nativeOrder())を使用して、ByteBufferインスタンスのエンディアンを現在のプラットフォームに合わせて調整します。

ByteBufferのエンディアンが正しく設定されたら、ByteBuffer.asIntBuffer()を使用してその表示をjava.nio.IntBufferとして取得し、データを入力します。

全例

import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.nio.IntBuffer; 

public class Test { 
    static final int bytes_per_datum = 4; 

    public static void main(String args[]) { 
     main2("Native Endian", ByteOrder.nativeOrder()); 
     main2("Big Endian", ByteOrder.BIG_ENDIAN); 
     main2("Little Endian", ByteOrder.LITTLE_ENDIAN); 
    } 

    static void main2(String comment, ByteOrder endian) { 
     int[] data = { 1, 0xF, 0xFF, 0xFFF, 0xFFFF, 0xFFFFF, 0xFFFFFF, 0xFFFFFFF, 0xFFFFFFFF }; 
     ByteBuffer bb = ByteBuffer.allocateDirect(data.length * bytes_per_datum); 
     bb.order(endian); // endian must be set before putting ints into the buffer 
     put_ints(bb, data); 

     System.out.println(comment + ": "); 
     print(bb); 
    } 

    static void put_ints(ByteBuffer bb, int[] data) { 
     IntBuffer b = bb.asIntBuffer(); // created IntBuffer starts only from the ByteBuffer's relative position 
             // if you plan to reuse this IntBuffer, be mindful of its position 
     b.put(data); // position of this IntBuffer changes by +data.length; 
    } // this IntBuffer goes out of scope 

    static void print(ByteBuffer bb) { // prints from start to limit 
     ByteBuffer bb_2 = bb.duplicate(); // shares backing content, but has its own capacity/limit/position/mark (equivalent to original buffer at initialization) 
     bb_2.rewind(); 
     for (int x = 0, xx = bb_2.limit(); x < xx; ++x) { 
      System.out.print((bb_2.get() & 0xFF) + " "); // 0xFF for display, since java bytes are signed 
      if ((x + 1) % bytes_per_datum == 0) { 
       System.out.print(System.lineSeparator()); 
      } 
     } 
    } 
} 
+0

こんにちは、最後の行は、 "asIntBufferは解決できないか、フィールドではありません"というエラーを返します。 – HardCoder

+0

申し訳ありませんが、私の間違い。私はそれを16時間まっすぐにしており、間違いなく休憩が必要です。あなたのお手伝いをありがとうございます。 – HardCoder

+0

まだあなたの質問が編集されています。私はあなたが何をしているのか正確にはわかりませんが、C++からPNGをロードする必要がある場合は、素晴らしいstd_imageライブラリを使用してください:http://nothings.org/stb_image.c –

2

あなたは、このように行列に変換することができます:

public static final byte[] intToByteArray(int value) { 
    return new byte[] { 
      (byte)(value >>> 24), 
      (byte)(value >>> 16), 
      (byte)(value >>> 8), 
      (byte)value}; 
} 

int[] arrayOfInt = {1,2,3,4,5,6}; 
byte[][] matrix = new byte[arrayOfInt.length][size]; 
for(int i=0;i<arrayOfInt.length;i++) 
    byte[i] = intToByteArray(arrayOfInt[i]); 
+1

私はByteArrayを誤って書きましたが、ByteBuffer型を意味していました。しかし、私はコードの別の部分であなたが書いたことを実際に使うことができるので、どうもありがとう。 :-) – HardCoder

0

per the example mentioned hereとしてJNIを使​​用してC++やCコードに直接int[]配列を渡していないため、任意の理由は?

+0

こんにちは、お返事ありがとうございます。私がそれを変更したくない理由は、JNIとのやりとりがかなりあり、私は常にデータ転送のためにByteBufferを渡して、そのように保ちたいと考えています。 – HardCoder

関連する問題