我知道这里的一些帖子涵盖了这个问题的一部分,我查看了它们并测试了一些但没有运气。我有这个本机方法签名,它应该用结果填充提供的CBadgeData 结构数组:
int elc_GetBadges(int nHandle, char* cErr, int* nRecCount, CBadgeData** arr)
CBadgeData结构实现如下:
package test.elcprog;
import java.util.Arrays;
import java.util.List;
import com.sun.jna.Pointer;
import com.sun.jna.Structure;
public class CBadgeData extends Structure{
public static class ByReference extends CBadgeData implements Structure.ByReference { }
public int nBadgeID, nTrigger, nExtraData;
public String cName;
public CBadgeData(Pointer pointer){
super(pointer);
}
public CBadgeData(){ }
public String ToString() {
return nBadgeID + "," + nTrigger + "," + nExtraData + "," + cName;
}
@Override
protected List getFieldOrder() {
String[] s = new String[]{"nBadgeID","nTrigger","nExtraData","cName"};
return Arrays.asList(s);
}
}
我最后一次尝试制作这个参数并调用该方法如下所示:
CBadgeData.ByReference[] badges = new CBadgeData.ByReference[max_items];
new CBadgeData.ByReference().toArray(badges);
int ret = inst.elc_GetBadges(handle, err, recCount, badges);
它因分段错误而失败。
我的问题是这里应该提供什么 Java 类型作为调用中的 native 的CBadgeData**
参数elc_GetBadges
?
编辑-1-
自己填充数组(有或没有终止空指针)不起作用并导致进一步的 Seg 崩溃。然后我使用 Pointer[] arg 作为技术建议:
Pointer[] pointers = new Pointer[max_items];
for(int i=0; i<max_items; i++){
pointers[i] = new CBadgeData.ByReference().getPointer();
}
int ret = inst.elc_GetBadges(handle, err, recCount, pointers);
这没有导致错误,但似乎没有对返回的结构进行任何更改,在这种情况下应该包含 4 个项目:
int bid = new CBadgeData(pointers[i]).nBadgeID; // this returns null for all items
在结构上使用显式 read() / write() 导致 Seg 再次崩溃(在读取时):知道我在这里还缺少什么吗?
编辑-2-
有趣的是 -Memory.get
在调用本机方法后直接使用,得到正确的结果:
Memory m= (Memory)pointers[0];
System.out.println("1st int: "+m.getInt(0)); // this gets 24289 which is 5ee1
System.out.println("2nd int: "+m.getInt(4)); // this gets 3
System.out.println("3rd int: "+m.getInt(8)); // this gets 255
System.out.println("String: "+m.getString(12)); // this gets "Badge[5EE1]" as supposed
但read()
仍然崩溃。有什么想法吗?