我尝试用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)
非常感谢!
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。