2013-05-22 1 views
0

다음은 제안 사항을 구현 한 후 업데이트 된 코드입니다. 그러나 여전히 문제는 지속됩니다. 심지어 메모리 덤프를 확인구조체의 배열을 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) 

, 구조가 할당되는 저장 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

질문을 업데이트하여 시도한 내용을 반영하십시오. 네이티브 함수는 배열에 얼마나 많은 구조체가 있는지를 어떻게 알 수 있습니까? BTW,'Structure.ByReference'는 구조체가 인수로 전달 될 때 불필요합니다. – technomage

+0

JNA 설명서에 제안 된대로 allocateMemory()를 사용했지만 성공하지 못했습니다. ( –