2013-05-22 35 views
0

這是我實現建議後的更新代碼。但仍然存在問題。使用JNA將包含字符數組的char數組結構傳遞給本地函數時出錯

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) 

我甚至檢查內存轉儲,結構似乎被分配存儲correctly.Structure大小也是正確= 200個字節 關於此錯誤的任何線索?

+0

就結構數組的大小而言,它是固定的。在本機代碼中使用#define .. –

回答

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)將兩者的工作,儘管後者是更準確,更明確地傳達你的意圖。

+0

感謝您的回覆。我嘗試了你的建議,但它仍然給我同樣的錯誤。 –

+0

更新您的問題以反映您嘗試的內容。你的本地函數如何知道它得到的數組中有多少結構?順便說一句,當結構作爲參數傳遞時,'Structure.ByReference'是多餘的。 – technomage

+0

在JNA文檔中建議使用allocateMemory(),但沒有成功:( –

相關問題