2013-12-11 1 views
2

붉은 모자 리눅스 플랫폼에서 네이티브 라이브러리에 대한 구조체에 대한 포인터를 전달하는 예제를 작업 중입니다. 나는 FAQ와 지침을 따라 here을 받았다. 지금까지 아무 것도 효과가 없었습니다. 내 네이티브 코드는 아래와 같이 진행됩니다JNA에서 구조체에 포인터를 전달하는 방법은 무엇입니까?

typedef struct Code 
{ 
    unsigned char a; 
    unsigned char b; 
    unsigned char c; 
    unsigned char d; 
    unsigned char e; 
    unsigned char f; 
} CODE; 

void printStruct(CODE * code) { 

    printf("OBIS value =%d.%d.%d.%d.%d.%d \n ", code->a, code->b, code->c, code->d, code->e, code->f); 

} 

과 같은 내 자바 코드 :

public class JNATest { 


    interface CLibrary extends Library { 
     public static class CODE extends Structure { 
      public int a=0,b=1,c=2,d=3,e=4,f=5; 
      public CODE() { 
       allocateMemory(); 
       autoWrite(); 
      } 
      public CODE(Pointer p) { 
       super(p); 
      } 
      @Override 
      protected List getFieldOrder() { 
       return Arrays.asList(new String[]{"a", "b", 
         "c", "d", "e", "f"}); 
      } 

      public static class ByReference extends CODE implements Structure.ByReference {}; 
      public static class ByValue extends CODE implements Structure.ByValue {}; 
     } 

     CLibrary INSTANCE = (CLibrary) Native.loadLibrary("./libStructTest.so", CLibrary.class); 
     void sayHello(String name); 
     void printStruct(CODE obis); 
    } 
    /** 
    * @param args 
    */ 
    public static void main(String[] args) { 
     try { 
      CLibrary.INSTANCE.sayHello("Sara"); 
      struct.JNATest.CLibrary.CODE obis = new struct.JNATest.CLibrary.CODE(); 
      obis.writeField("a", 0); 
      obis.writeField("b", 0); 
      obis.writeField("c", 1); 
      obis.writeField("d", 0); 
      obis.writeField("e", 0); 
      obis.writeField("f", 255); 
      obis.write(); 

      Pointer ptr = obis.getPointer(); 
      System.out.println("ptr = " + ptr.toString()); 
      CLibrary.INSTANCE.printStruct(obis); 
      Pointer p = obis.getPointer();        
      System.out.println(obis.size() + ":c=" + obis.c); 

      System.out.println(obis.size() + ":c=" + obis.c); 

     } catch (UnsatisfiedLinkError e) { 
      System.out.println("Exception" + e); 
     } 
    } 
} 

나는 구조 멤버 변수 A, B, C에 전달 된 값을 받고 있지 않다 자바 프로그램을 시도하면서, d, e, f하지만 항상 0입니다.

ptr = [email protected] (24 bytes) 
OBIS value =0.0.0.0.0.0 
24:c=1 
24:c=1 

여기 Java 코드에서 뭔가가 누락 되었습니까? 어떤 도움이라도 대단히 감사합니다. 미리 감사드립니다.

+0

는 참조 http://stackoverflow.com/questions/1632367/passing-pointers-between-c-and-java-through-jni 또는 http://stackoverflow.com/questions/6543396/passing-pointers-between -c-and-java-through-jni – Madhura

답변

0

JNA에서 수행 한 자동 마샬링보다 높은 성능을 발견 했으므로 이전에 패턴을 사용했습니다. 한번 해봐.

첫째, 구조 :

public class Code { 
    private Pointer pointer; 

    Code() { 
     long memory = Native.malloc(6); 
     pointer = new Pointer(memory); 
    } 

    void free() { 
     Native.free(Pointer.nativeValue(pointer)); 
    } 

    Pointer getPointer() { 
     return pointer; 
    } 

    byte getA() { 
     return pointer.getByte(0); 
    } 

    byte getB() { 
     return pointer.getByte(1); 
    } 

    byte getC() { 
     return pointer.getByte(2); 
    } 
    ... 

    void setA(byte a) { 
     pointer.setByte(0, a); 
    } 

    void setB(byte b) { 
     pointer.setByte(1, b); 
    } 

    void setC(byte c) { 
     pointer.setByte(2, c); 
    } 
    ... 
} 

다음, API :

class JNATest { 
    static { 
     Native.register("StructTest"); // undecorated name ... becomes libStructTest.so on Linux 
    } 

    public static native void printStruct(Pointer obis); 
} 

마지막으로, 사용 :

서로 다른 구조를 가지고있는 경우
Code code = new Code(); 
code.setA((byte) 'a'); 
code.setB((byte) 'b'); 
... 
JNATest.printStruct(code.getPointer()); 
code.free(); // free the memory allocated in the constructor 

, short와, int , longPointer cla ss는 읽기/쓰기 용이 한 접근자를 제공합니다.

+0

큰 브렛! 나는 당신이 제안한 패턴을 따라 갔다. 그것은 나를 위해 일했다. 고마워. – srvnn