使用JNA将包含char数组的结构数组传递给本机函数时出错

时间:2013-05-22 13:25:16

标签: java jna

这是我在实施建议后更新的代码。但问题仍然存在。

typedef struct S1{

 char temp1[100];
 char temp2[100];
 }S1
 ...
 int manipulateTemp(S1 s1Arr[] );

 JNA interface looks like this

 public interface Add extends Library
 {
     Add INSTANCE = (Add) Native.loadLibrary("add", Add.class);

     public static  class S1 extends Structure {
     public byte[] temp1 = new byte[100];
     public byte[] temp2 = new byte[100];
     public static class ByReference extends S1 implements Structure.ByReference {

     };

   };
   int manipulateTemp( S1[]);
 }
 //
 public static byte[] toByteArray(char[] a ,Charset c){
     CharBuffer cBuffer = CharBuffer.wrap(a);
     ByteBuffer bBuffer = c.encode(cBuffer);
     return bBuffer.array;
 }
 //in main method

 Add lib = Add.INSTANCE;
 Add.S1.ByReference s1Ref = new Add.S1.ByReference();
 Add.S1[] s1Arr = (Add.S1[])s1Ref.toArray(10);
 s1Ref.clear();
 //initialize array
 for(int i =0;i<s1Arr.lenth ;i++){
        byte[] data = toByteArray("myString1".toCharArray,Charset.defaultCharSet
        System.arrarycopy(data,0, s1Arr[i].temp1,0,data.length);
         data = toByteArray("myString2".toCharArray,Charset.defaultCharSet
        System.arrarycopy(data,0, s1Arr[i].temp2,0,data.length);
 }


 // calling native function
 lib.manipulateTemp(s1Arr[]);

 After execution 
 Exception in thread "main" java.lang.Error: Invalid memory access
at com.sun.jna.Function.invokeInt(Native Method)
at com.sun.jna.Function.invoke(Function.java:344)
at com.sun.jna.Function.invoke(Function.java:276)
at com.sun.jna.Library$Handler.invoke(Library.java:216)
at com.sun.proxy.$Proxy0.manipulateTemp((Unknown Source)
at LoanTest.newTestCalc.main(newTestCalc.java:288)

我甚至检查了内存转储,结构似乎被正确分配存储。结构大小也正确= 200字节      有关此错误的任何线索?

1 个答案:

答案 0 :(得分:0)

您需要将值复制到现有的temp字段中,而不是覆盖它。当你覆盖它时,你实际上正在改变它的大小,JNA用它来确定结构大小。以下是如何初始化结构数据:

class S1 extends Structure {
    public byte[] temp = new byte[100];
    ...
}

S1 s = new S1();
S1[] array = (S1[])s.toArray(ARRAY_SIZE);
System.setProperty("jna.encoding", "utf-8"); // You probably want utf-8; utf-16 has 16-bit code units, so unless your native code is actually expecting a utf-16 encoding broken down into byte units, use utf-8
byte[] data = Native.toByteArray("myString"); // includes NUL terminator
System.arraycopy(data, 0, array[0].temp, 0, data.length);
// Repeat as needed for other members of the array
lib.manipulateTemp(array);

请注意,声明manipulateTemp(S1 s)manipulateTemp(S1[] array)都可以使用,但后者更准确并明确传达您的意图。