JNA 二维数组

JNA two dimensional arrays

我尝试用 JNA 在 C 中调用一个 short**。

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]);
        }
    }
}

但我得到 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);

结果:

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

非常感谢!

JNA 仅处理一维数组。

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

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

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

的一部分

new short[] {1, 2, 3, 4} 在这里不起作用,因为您还没有分配 native-side 内存来支持该数组的 java 内存。您使用 Memory class 进行的内存分配是正确的。

在 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));

现在,您可以编写数组值了。您可以使用 offset 和 setShort() 遍历列,但您也可以直接使用 Pointer.write() 编写,例如

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

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