2012-09-03 88 views
0

我當前正在嘗試使用來自Java的NTX索引訪問DBF。我有許多年前的Artemis引擎(現在是ApolloDB)的副本,它在VB6中執行此操作。它主要使用3個DLL,主要是SDE32.DLL。Java NativeCall庫返回數據類型

我已經使用成功訪問許多在這些DLL功能NativeCall

public static VoidCall sx_Zap = new VoidCall("SDE32", "sx_Zap"); public static IntCall sx_Use = new IntCall("SDE32", "sx_Use");

intFile = sx_Use.executeCall(fileName); 
     if (intFile == 0){ 
      if (JOptionPane.showOptionDialog(null, "Could not open:" + fileName + "\nRetry?", "Failed to open DBF", JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE, null, null, null) != JOptionPane.YES_OPTION){ 
       return; 
      }else{ 
       sx_Zap.executeCall(); 
      } 
     } 

該代碼會很愉快地打開和ZAP的數據庫,所以我知道我在正確的軌道上。請注意,當我想要返回一個整數和一個VoidCall時,我使用了一個IntCall,當我不想返回任何東西時。

我發現的問題是,像一些數據訪問函數的一些函數返回字符串,例如函數聲明在VB6中爲sx_GetString函數從當前記錄獲取一個字符串字段。 Declare Function sx_GetString Lib "sde32.dll" (ByVal cpFieldName As String) As String

如何將這些信息導入到Java中?似乎只有int(和布爾)和void返回類型,我怎樣才能返回String,double和long類型?

使用JNA我可以訪問雙打和長整型似乎但當我嘗試一個字符串返回類型時,我得到執行保護違規和Java崩潰了。

JNA示例:

public interface SDE32 extends Library { 
    public String sx_GetString(String cpFieldName); 
    public Double sx_GetDouble(String cpFieldName); 
    public Long sx_GetLong(String cpFieldName); 

}

JNADBF.SDE32 sde = (JNADBF.SDE32) Native.loadLibrary("SDE32", JNADBF.SDE32.class); 
    System.out.println(sde.sx_GetString("TILLNAME")); 
    System.out.println(sde.sx_GetDouble("SELLPRICE")); 

JNA錯誤:

Execution protection violation

#

# A fatal error has been detected by the Java Runtime Environment:

#

# EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x00000000, pid=11104, tid=11060

那麼如何才能得到這些返回類型?尤其是String。

任何幫助將不勝感激。

回答

1

我建議首先返回一個指針(而不是字符串),然後使用各種指針方法來檢查它指向的內存。一旦你理解了函數返回的內容,你可以弄清楚如何讓JNA正確地(自動或顯式地)恢復數據。

編輯

public interface SDE32 extends StdCallLibrary { 
    public Pointer sx_GetString(String cpFieldName); // don't use String just yet 
    public double sx_GetDouble(String cpFieldName); 
    // Don't use Java "long" unless you want a 64-bit integer 
    // On windows, native "int" and "long" are both 32 bits 
    public NativeLong sx_GetLong(String cpFieldName); 
} 

編輯 談到pascal header files一個較新的版本,您應該使用Java類型shortsmallIntWordBool,並intLong。但是,切換到這些類型並不能提供完整的修復(這會減少堆棧損壞 - 您將用打錯的標誌「打開」DB)。

+0

我似乎無法返回一個指針,我得到了同樣的錯誤。你能否爲我提供一個示例路線,以便我可以確認我不只是做錯了? – feldoh

+0

嘗試擴展StdCallLibrary而不是Library。 VB通常要求被調用的DLL使用stdcall調用約定(或至少默認使用它);要在JNA中使用stdcall,你需要實現StdCallLibrary接口。 – technomage

+0

不,仍然是一樣的錯誤,我可以通過電子郵件發送給你的DLL或上傳到互聯網或其他東西;那麼如果你喜歡,你可以親自看到錯誤。 – feldoh