遇到小坑一则,已经填坑,特此记录方便后人。
由代码来说明:
C头文件如下:
有这个一个方法
char** GetArray(const Result* Result);
该方法的参数先不说,仅仅是一个结构体指针。对于如何使用结构体指针请参见我之前的文章。
在JNA的使用方式中,对应的类型映射C中的char* 是java中的String. char **对应java中的String[]。详见下表:
上述方法对应的java实现为:
PointerByReference GetArray(PointerByReference Result);
我首次提取数组的方法如下:
PointerByReference pointerByReference = INSTANCE.GetArray(result);
Pointer value = pointerByReference.getValue();
String[] stringArray = value.getStringArray(0);
for(String result: stringArray){
System.out.println(result);
}
这种方式总会报出Invalid memory access的异常。
于是乎我换了一种方式如下:
PointerByReference pointerByReference = INSTANCE.GetArray(result);
Pointer value = pointerByReference.getValue();
Pointer[] pointerArray = value.getPointerArray(0);
for(Pointer pointer: pointerArray ){
String result = pointer.getString(0,"utf-8");
System.out.println(result);
}
问题依旧如此。
到此刻我非常的纳闷,我获取的Pointer数组在Debug下可以看到长度为2,但是怎么就取不出值呢?
于是乎研究了一下JNA的接口文档。以及查了一些资料,其中一句话非常重要:
getStringArray() assumes that your string array is going to be terminated with a NULL pointer to indicate the end
于是乎我重新看了一下C的头文件,发现` @out The returned array will contain a NULL value as last element.
于是我就明白了,我要得到的数组里就只有一个值,另一个是NULL,但是一个值为什么取不出呢?
于是我将我所有的代码都删除,重新实现,然后就发现了一个奇妙的地方。
PointerByReference pointerByReference = INSTANCE.GetArray(result);
pointerByReference .getPointer();
没错就是这里。我之前使用的是getValue。这样的方式无法得到数组,而只能通过该Pointer对象的getString方法得到数组中的一个值。
而使用gtePointer,就可以得到全部的数组了。实现代码如下
PointerByReference pointerByReference = INSTANCE.GetArray(result);
Pointer value = pointerByReference.getPointer();
String[] stringArray = value.getStringArray(0);
for(String result: stringArray){
System.out.println(result);
}
至此,此坑填满。ヾ( ̄▽ ̄)ByeBye