0

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

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 字节关于这个错误的任何线索?

4

1 回答 1

0

You need to copy values into the existing temp field, not overwrite it. When you overwrite it, you're actually changing its size, which JNA uses to determine the structure size. Following is how you should initialize your structure data:

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);

Note that the declarations manipulateTemp(S1 s) or manipulateTemp(S1[] array) will both work, although the latter is more accurate and conveys your intent explicitly.

于 2013-05-22T18:07:33.580 回答