2011-06-15 128 views
2

我想要將一個指向C結構的指針轉換爲jna結構。我使用jna從dll接收回調函數,該函數有一個參數,該參數是指向C結構的指針,當我嘗試將指針轉換爲jna結構時,我得到錯誤的結構值。如何將一個指向c結構的指針轉換爲jna結構

這是C結構:

typedef struct 
{ 
    int x; 
    int y; 
}Point; 
Point *gpt; 

typedef struct 
{ 
    int x; 
    int y; 
    Point pt1; 
}Point2; 
Point2 *gpt2; 

也就是說在C回調函數的指針(void *的PARAMS),以點2 sctruct:

void __stdcall PointCallback(void *params, int param_size) 

所以,我做了這個java中的代碼接收回調並獲得原始結構:

// Point.java  
package Callback.UsePointLib; 
import com.sun.jna.Structure; 

public class Point extends Structure 
{ 
    public static class ByValue extends Point implements Structure.ByValue {} 
    public int x; 
    public int y; 
} 

//Point2.java 
package Callback.UsePointLib; 
import com.sun.jna.Pointer; 
import com.sun.jna.Structure; 

public class Point2 extends Structure { 
     public int x; 
     public int y; 
     Point pt1; 
     public Point2(Pointer p){ 
      super(p); 
     } 
} 

回調執行:

//UsePointLib.java 
public interface IFuncCallback extends StdCallCallback{ 
     void callback(Pointer Params, int ParamSize); 
    } 
    public class FuncCallback implements IFuncCallback{ 
    @Override 
    public void callback(Pointer Params, int ParamSize) { 
     Point2 pt2; // = new Point2(); 
     pt2 = new Point2(Params); 
     System.out.println("pt2.x = "+pt2.x);  **<- I get zero here instead of four** 
     System.out.println("pt2.y = "+pt2.y);  **<- I get zero here instead of five** 
     System.out.println("pt2.pt1.x = "+pt2.pt1.x);**<- pt1 is null, throwing exception** 
     System.out.println("pt2.pt1.y = "+pt2.pt1.y);**<- same as pt1.** 
    } 
    } 

我做了一個C程序來訪問DLL並接收回調,它工作正常,它收到正確的值。所以,問題是我的java代碼。我嘗試了許多替代品,但都沒有成功。

請,我會很感激任何幫助。

謝謝,

費爾南多。


編輯

我已經修改了代碼,它的工作原理部分。

//UsePointLib.java 
    public interface IFuncCallback extends StdCallCallback{ 
      void callback(Pointer Params, int ParamSize); 
     } 
     public class FuncCallback implements IFuncCallback{ 
     @Override 
     public void callback(Pointer Params, int ParamSize) { 
      Point2 pt2; // = new Point2(); 
      pt2 = new Point2(Params); 
       *pt2.read();* **<--Modification** 
      System.out.println("pt2.x = "+pt2.x);  **<- I get the correct value (four)** 
      System.out.println("pt2.y = "+pt2.y);  **<- I get the correct value (five)** 
      System.out.println("pt2.pt1.x = "+pt2.pt1.x);**<- pt1 is still null, throwing exception** 
      System.out.println("pt2.pt1.y = "+pt2.pt1.y);**<- same as pt1.** 
     } 
     } 

回答

0

jna文檔說,構造函數Structure(指針)分配一個結構到預先分配的內存。它不會自動爲你分配值。我不認爲你想要的。

更改構造函數

public Point2(){ 
    super(); 
} 
public Point2(Point1 p){ 
    super(); 
    pt1.x = p.x; 
    pt1.y = p.y; 

    this.x = something; 
    this.y = something; 
} 
+0

嗨阿布吉斯,謝謝你的幫助。我閱讀jna文件,我知道,但是,我要做的是將數據從dll中的結構複製到java內存中。 – Fernando 2011-06-16 14:19:39

+0

這是一個CTI應用程序,dll由cti卡供應商提供,回調是從卡上接收事件(響鈴,呼叫應答等)。所以,我把回調放在一個線程中,我使用消費者/生產者將事件數據通過隊列傳遞給另一個線程。這是因爲我需要將收到的指針所指向的內容複製到本地內存。我將編輯我的帖子以提供一個可能的解決方案。 – Fernando 2011-06-16 14:35:51

0

在回調的背景下,JNA將自動調用Structure.read入境和Structure.write退出類型結構的任何參數。

如果您聲明回調方法簽名使用適當子類的結構類型(在您的示例中爲「Point2」),則應該自動複製到本機內存或從本機內存複製。

+0

嗨Technomage,我不能繼承,因爲回調指向基於以前的條件多個C結構。例如,在一次調用中params指向struct PointX,在另一次調用時它指向struct PointY,它與PointX完全不同。經過一些嘗試,我已經使用strucuture構造函數傳遞接收的指針來解決問題。在構造函數中,我使用了useMemory(指針p)來映射本機內存。這是可能的,因爲我知道每個調用都指向了c結構,所以我可以使用正確的java結構覆蓋它的構造函數。謝謝。 – Fernando 2011-07-02 15:21:49

+0

如果使用3.3.0或更高版本,請使用Structure(Pointer)ctor而不是useMemory(Pointer);後者將不必要地分配內存。 – technomage 2011-10-04 15:35:57