JNA二维数组

Phi*_*ter 6 java jna

我尝试用JNA在C中调用短**.

C看起来像这样:

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]);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)
  • 从JNA传递短[] []不起作用.

  • JNA文档说"要映射本机多维数组,使用一维Java数组",但它不起作用.打电话的时候

    'nativeLib.compute(new short [] {1,2,3,4},2,2); 我得到:java.lang.Error:com.sun.jna.Native.invokeVoid(本机方法)的内存访问无效

  • 似乎需要一个PointerByReference,我试图用PointerByReference填充PointerByReference,它包含短值,但它不起作用:

    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);
    }
    
    Run Code Online (Sandbox Code Playgroud)
  • 我也尝试过:

        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);
    
    Run Code Online (Sandbox Code Playgroud)

但我明白了 in[0][0] = 3184 in[0][1] = 10460 in[1][0] = 3344 in[1][1] = 10460

有没有人有想法?我不能改变C签名,我要处理这个简短的**

非常感谢.

我终于成功了!这样做:

        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);
Run Code Online (Sandbox Code Playgroud)

结果如下:

in[0][0] = 1
in[0][1] = 2
in[0][2] = 3
in[1][0] = 4
in[1][1] = 5
in[1][2] = 6
Run Code Online (Sandbox Code Playgroud)

非常感谢!

Dan*_*dis 2

JNA 仅处理一维数组。

从技术上讲,C 也是如此。Ashort *可以是 1d、2d 或 3d 数组。除非你了解内部原理,否则你不会知道。只有通过阅读文档,您才知道该函数需要一个二维数组。您真正要做的就是将指针传递给数组的第一个元素(总长度 row*col),然后使用 (rowIndex * col + colIndex) 获取结果。在 JNA 中,您只需使用一维数组来匹配。

然而,在这种情况下,您有一个,short **因此您知道您有一个一维指针数组,每个指针都指向一个一维数组shorts。Pointer[]在 JNA 中,您为第一个 *创建一个指针数组 ( ); 每个都将指向新行的第一“列”(第二个 *)。

Invalid Memory Access错误表明您没有正确分配本机内存,并强烈提示您答案:您不能简单地将原始数组作为参数传递。您必须通过使用类Memory或将数组作为Structure.

此处new short[] {1, 2, 3, 4}不起作用,因为您尚未分配本机端内存来支持该数组的 java 内存。通过使用该类进行的内存分配,您走在正确的轨道上Memory

在 C 中,short** in需要一个指针数组。因此,您应该首先声明一个指针数组:

Pointer[] p = new Pointer[row];
Run Code Online (Sandbox Code Playgroud)

然后,您将为每一行设置指针,分配内存:

p[0] = new Memory(col * Native.getNativeSize(Short.TYPE));
p[1] = new Memory(col * Native.getNativeSize(Short.TYPE));
Run Code Online (Sandbox Code Playgroud)

现在,您可以写入数组值。您可以使用偏移量迭代列,setShort()但也可以使用Pointer.write()直接写入,例如,

p[0].write(0, new short[] {1, 2}, 0, 2);
p[1].write(0, new short[] {3, 4}, 0, 2);
Run Code Online (Sandbox Code Playgroud)

然后您将传递p给本机 C for in