2017-02-08 8 views
1

私はC++ dll usnig JNAにアクセスするJavaアプリケーションを作成しています。だから私はJNAとC + + thridパーティdllの間で通信するためのC DLLを用意しました。JNAを使ってjavaでchar *を含む構造体を渡し、データのコピーを避けるには?

Cコード:

struct Struct1 
    { 
    uint32_t Size; 
    unsigned char* Data; 
    }; 
    struct Struct2 
    { 
    uint32_t Struct1_Nbr; 
    Struct1* struct1_elements; 
    }; 
    bool Open(char* fileName, Struct2** struct2); 

今、私はJavaアプリケーションで対応するJNAコードを書いていますし、私はそれがあるとして、このデータをコピーせずに「unsigned char型*データ」にアクセスしたい私は、これら二つの構造体を持っています大量のデータ。 "メモリ"または "ポインタ" JNAタイプを使用してこのタスクを実行するにはどうすればよいですか?何かアドバイスは非常に高く評価されるだろう

public class Test 
    { 
    public static class Struct1 extends com.sun.jna.Structure {   
    public Struct1(){} 
    public Struct1(Pointer pointer){ 
     super(pointer); 
     read(); 
    } 

    public static class Struct1ByValue extends Struct1 implements com.sun.jna.Structure.ByValue{}; 
    public int Size; 
    public Memory Data; 
    public static class Struct1ByReference extends Struct1 implements com.sun.jna.Structure.ByReference{} 

    @Override 
    protected List getFieldOrder() { 
     // TODO Auto-generated method stub 
     return Arrays.asList("Size", "Data"); 
    }; 

public static class Struct2 extends com.sun.jna.Structure {  
    public Struct2(){} 
    public Struct2 (Pointer pointer){ 
     super(pointer); 
     read(); 
    } 
    public int Struct2_Nbr; 
    public Struct1.Struct1ByReference struct1_elements = new Struct1.Struct1ByReference(); 

    public static class Struct2ByValue extends Struct2 implements com.sun.jna.Structure.ByValue{}; 
    public static class Struct2ByReference extends Struct2 implements com.sun.jna.Structure.ByReference{} 

    @Override 
    protected List getFieldOrder() { 
     // TODO Auto-generated method stub 
     return Arrays.asList("Struct1_Nbr", "struct1_elements")); 
    }; 
} 
    public interface StructureProtocol extends com.sun.jna.Library{ 
    Boolean Open(String fileName, PointerByReference struct2); 
    } 
    public StructureProtocol lib; 
    public Test(){ 
    this.lib = (StructureProtocol) Native.loadLibrary("TestAPI", StructureProtocol.class); 
} 

    public static void main(String[] args) { 

      Test test = new Test(); 
    PointerByReference pref = new PointerByReference(); 

    test.lib.Open("filePath", pref); 
    Pointer ptr = pref.getValue(); 
    Struct2 struct2= new Struct2(ptr); 
    Struct1[] struct1_array= (Struct1[])(struct2.struct1_elements).toArray(struct2.struct1_Nbr); 
    System.out.println("struct1_array[0]: Size = " + struct1_array[0].Size); 
    System.out.println("struct1_array[0]: Data= " + struct1_array[0].Data); 
    } 
    } 

は、ここに私の試みです。ここで

+0

あなたの試行は何ですか?エラー?予期しない結果? – Alex

+0

私は期待される結果を得ます:System.out.println( "Struct2.struct1_Nbr ==" + struct2。struct1_Nbr); Struct1 [] struct1_array =(Struct1 [])(struct2.struct1_elements).toArray(struct2.struct1_Nbr); "この命令には例外があります。 – benayedh

答えて

0

は私のSolutiuon、最初のドラフトです:

  1. 構造

    (com.sun.jna.Structure)

    を拡張するJavaのクラスを宣言します(クラスのすべてのフィールドはに公開する必要があります。そうでないと、エラーが発生します。電子構造は、宣言)クラスが測定できない

    public class Struct1 extends Structure{ 
        public int Size; 
        public String Data; 
    } 
    
  2. を拡張し、(I、構造を作成し、テスト用の値でそれを充填した引数として構造体へのポインタをとるC DLL内のメソッドを定義します)

    void __declspec(dllexport) GetStruct(Struct1* a){ 
    Struct1 s; 
    s.Size = 9; 
    s.Data = "Output"; 
    *a = s; 
    } 
    
  3. )私はあなたがすでに正常C DLLへのJavaアプリを接続することを前提としていたので、私は私の仮定が間違っている場合は、(その部分をスキップし、コメントで教えてください、私は私の答えを編集
  4. tを追加するとJavaコードにHESEライン(ノートCDLLが私のCライブラリへのハンドルです)

    Struct1 test = new Struct1(); 
    cdll.GetStruct(test); 
    System.out.println("Struct1: " + test.Size + " " + test.Data); 
    

あなたは構造体s C DLL内からデータを取得する必要があります。

+1

'String'を使って任意のデータブロックを表現するのは悪い考えです。 – technomage

0

データフィールドが任意のデータを指している場合は、Pointerを使用します。ネイティブ側が割り当てる場合、あなたは何もしません。 Java側が割り当てる場合は、Memoryオブジェクトをそのフィールドに割り当てます。 struct*struct**については

、それは彼らはいくつかのあいまいさがあるので、何を表しているか伝えるために、これらの構築物を用いて、いくつかのネイティブコードを参照することが有用であると思います(struct*は、単一構造体へのポインタである、または可能性それらの連続した配列へのポインタ)。 struct**は、struct*の返却のために割り当てられた記憶域である可能性があります。

関連する問題