我尝试使用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]);
}
}
}
从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);
}
我也尝试过:
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);
但我得到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
非常感谢!
答案 0 :(得分:2)
JNA只处理单维数组。
而且,从技术上讲,C也是如此。short *
可以是1d,2d或3d数组。除非你知道内部,否则你不会知道。只有通过阅读文档才能知道该函数需要2D数组。您所做的只是将指针传递给数组的第一个元素(总长度行* col),然后使用(rowIndex * col + colIndex)来获取结果。在JNA中,您只需使用一维数组进行匹配。
但是,在这种情况下,你有一个short **
,所以你知道你有一个指针数组,每个指针都指向short
的一维数组。在JNA中,您为第一个*创建一个指针数组(Pointer[]
);每个都将指向新行的第一个“列”(第二个*)。
Invalid Memory Access
错误表示您没有正确分配本机内存,并给出了强烈的答案提示:您不能简单地将原始数组作为参数传递。您必须使用Memory
类或将数组作为Structure
的一部分来分配其内存。
new short[] {1, 2, 3, 4}
在这里不起作用,因为你没有分配本机内存以支持该数组的java内存。通过使用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));
现在,您可以编写数组值。您可以使用偏移量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。