2017-02-04 9 views
6

JNA를 사용하여 C에서 short **를 호출하려고합니다.JNA 2 차원 배열

는 C는 다음과 같다 : A는 단 [] [] JNA 작동하지 않는로부터 전달

void compute(short** in, int row, int col) { 
    for (int i = 0; i < row; i++) { 
     for (int j = 0; j < col; j++) { 
      printf("in[%d][%d] = %d\n", i,j, in[i][j]); 
     } 
    } 
} 
  • .

  • JNA 설명서에 "기본 다차원 배열을 매핑하려면 1 차원 Java 배열을 사용합니다"라고되어 있지만 작동하지 않습니다. 전화 할 때

    'nativeLib.compute (new short [] {1, 2, 3, 4}, 2, 2); 내가 얻을 : 상위를 : com.sun.jna.Native.invokeVoid (기본 방법)에서 잘못된 메모리 액세스

    PointerByReference이 필요한 것으로 보인다
  • , 내가 포함 PointerByReference으로 PointerByReference을 채우기 위해 노력 짧은 값하지만이 작동하지 않습니다

    Pointer pointer = new Memory(4*Short.SIZE); 
    
    Pointer pointer1 = new Memory(2*Short.SIZE); 
    pointer1.setShort(0,(short)1); 
    pointer1.setShort(Short.SIZE,(short)2); 
    
    Pointer pointer2 = new Memory(2*Short.SIZE); 
    pointer2.setShort(0,(short)3); 
    pointer2.setShort(Short.SIZE,(short)4); 
    
    pointer.setPointer(0, pointer1); 
    pointer.setPointer(2*Short.SIZE, pointer2); 
    
    nativeLib.compute(new PointerByReference(pointer), 2,2); 
    

하지만를 얻을 :

Pointer pointerOfArray = new Memory(row * col * Native.getNativeSize(Short.TYPE)); 
for(int i=0;i<row;i++) { 

    Pointer pointer = new Memory(col * Native.getNativeSize(Short.TYPE)); 
    for(int j=0;j<col;j++) { 
     pointer.setShort(j*Native.getNativeSize(Short.TYPE), in[i][j]); 
    } 
    pointerOfArray.setPointer(i*row*Native.getNativeSize(Short.TYPE), pointer); 
} 
  • 는 또한 시도

    누구나 아이디어가 있습니까? C 시그니처를 변경할 수 없습니다.이 짧은 것을 처리해야합니다 **

    고마워요.

    솔루션

    나는 finnaly가 성공! 이 일을 : 결과와

     short[][] in = { 
          {1,2,3}, 
          {4,5,6}, 
        }; 
    
        Pointer[] data = new Pointer[in.length]; 
        for(int i=0;i<in.length;i++) { 
         data[i] = new Memory(2*Short.SIZE); 
         data[i].write(0, in[i], 0,in[0].length); 
        } 
    
        nativeLib.compute(data, in.length,in[0].length); 
    

    :

    in[0][0] = 1 
    in[0][1] = 2 
    in[0][2] = 3 
    in[1][0] = 4 
    in[1][1] = 5 
    in[1][2] = 6 
    

    감사합니다 많이!

  • +0

    "포인터의 배열"버전이 당신을 위해 일해 준 것을 기쁘게 생각합니다! –

    답변

    2

    JNA는 단일 차원 배열 만 처리합니다.

    기술적으로는 C. short *은 1d, 2d 또는 3d 배열 일 수 있습니다. 내부를 알지 못하면 알 수 없습니다. 문서를 읽는 것만으로 함수가 2D 배열을 기대하고 있음을 알 수 있습니다. 실제로하고있는 일은 배열의 첫 번째 요소 (전체 길이 행 * col)에 포인터를 전달한 다음 (rowIndex * col + colIndex)를 사용하여 결과를 가져 오는 것입니다. JNA에서는 1D 배열을 사용하여 일치시킬 수 있습니다.

    그러나이 경우 short **을 가지므로 1D 배열 short을 가리키는 1D 포인터 배열을 알고 있습니다. JNA에서는 첫 번째 *에 대한 포인터 배열 (Pointer[])을 만듭니다. 각각은 새 행의 첫 번째 열 (두 번째 *)을 가리 킵니다.

    Invalid Memory Access 오류는 사용자가 네이티브 메모리를 올바르게 할당하지 못했음을 나타내며 그 답을 제공합니다. 단순히 프리미티브 배열을 매개 변수로 전달할 수 없습니다. Memory 클래스를 사용하거나 배열을 Structure의 일부로 포함하여 메모리를 할당해야합니다.

    해당 배열의 Java 메모리를 지원하기 위해 기본 메모리를 할당하지 않았기 때문에 new short[] {1, 2, 3, 4}이 여기에서 작동하지 않습니다. Memory 클래스를 사용하여 수행 한 메모리 할당을 제대로 수행하고있었습니다.

    C에서 short** in은 포인터 배열을 필요로합니다. 그래서 당신은 포인터의 배열을 선언하여 시작해야합니다

    Pointer[] p = new Pointer[row]; 
    

    은 그럼 당신은 메모리를 할당, 각 행에 대한 포인터를 설정합니다 :

    p[0] = new Memory(col * Native.getNativeSize(Short.TYPE)); 
    p[1] = new Memory(col * Native.getNativeSize(Short.TYPE)); 
    

    을 지금, 당신은 당신의 배열 값을 작성할 수 있습니다. 당신은

    p[0].write(0, new short[] {1, 2}, 0, 2); 
    p[1].write(0, new short[] {3, 4}, 0, 2); 
    

    는 그런 다음 in에 대한 네이티브 C에 p을 통과 할 것, 오프셋 열을 반복하고 setShort()하지만 당신은 또한 직접 Pointer.write() 예를 사용하여 작성할 수있다.

    +0

    첫 번째 해결 방법에 대해 'nativeLib.compute (new short [] {1, 2, 3, 4}, 2, 2);' a를 준다; "스레드에서 예외"주 "java.lang.Error : 잘못된 메모리 액세스 \t com.sun.jna.Native.invokeVoid (기본 메소드)" –

    +0

    내 답장을 업데이트했습니다 ... –

    +0

    도움을 주셔서 감사합니다. 그것은 모두 괜찮습니다. 그러나 두 가지 업데이트 된 솔루션을 사용하면 결과는 다음과 같습니다. [1] [1] [2]에있는 [0] [1] = 2에있는 [1] [0] = 3200의 [0] ] = 10525' –