2012-02-25 2 views
3

제목에 이미 말했듯이, int []를 Java의 ByteBuffer로 변환해야합니다. 이 작업을 수행 할 수있는 권장 방법이 있습니까?int []를 Java에서 ByteBuffer로 변환하는 방법?

JNI에서 ByteBuffer를 C++로 전달하려고합니다. 이 경우 특정 엔디안 변환과 관련하여 무엇을주의해야합니까?

편집 : 죄송합니다. 실수로 ByteArray를 작성했지만 ByteBuffer 유형을 의미했습니다.

편집 : 샘플 코드 :

나는 불필요한 부분을 제거했습니다. C++에서 JNI를 통해 Java 함수를 호출하여 리소스를로드하고 바이트 버퍼로 C++로 다시 전달합니다. 그것은 다양한 다른 리소스와 함께 작동합니다. 이제 "int []"가 있고 그것을 bytebuffer로 변환하는 우아한 방법이 있는지 또는 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 인스턴스의 endianness를 현재 플랫폼과 일치하도록 조정할 수 있습니다. ByteBuffer의 엔디안가 제대로 구성 후

java.nio.IntBuffer로의 전망을 얻을하고 데이터를 채우기 위해 ByteBuffer.asIntBuffer()를 사용합니다.

전체 예 :

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

는 C에 직접 int[] 배열을 전달 ++ 또는 C 코드가 per the example mentioned here으로 JNI를 사용하지 않는 이유라도?

+0

안녕하세요, 답장을 보내 주셔서 감사합니다. 나는 그것을 바꾸고 싶지 않다는 이유는 JNI와의 상호 작용이 매우 적기 때문에 항상 데이터 전송을 위해 ByteBuffer를 전달하고 그렇게 유지하려고합니다. – HardCoder

관련 문제