0

現在、Java から NTX インデックスを使用して DBF にアクセスしようとしています。私はVB6でこれを行うために何年も前からArtemisエンジン(現在はApolloDB)のコピーを持っています。主に SDE32.DLL の 3 つの DLL を使用します。

NativeCall を使用して、これらの DLL の多くの関数に正常にアクセスしました。

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();
            }
        }

そのコードは非常に喜んでデータベースを開き、ザップするので、正しい軌道に乗っていることがわかります. 整数を返したい場合は IntCall を使用し、何も返したくない場合は VoidCall を使用したことに注意してください。

私が見つけた問題は、一部のデータ アクセス関数のような一部の関数が文字列を返すことです。たとえば、現在のレコードから文字列フィールドを取得する sx_GetString 関数の VB6 の関数宣言です。 Declare Function sx_GetString Lib "sde32.dll" (ByVal cpFieldName As String) As String

この情報を Java に取り込むにはどうすればよいですか? 戻り値の型は int (および boolean) と void のみのようですが、String、double、および long 型を取得するにはどうすればよいですか?

JNA を使用すると、double と long にアクセスできるように見えますが、文字列の戻り値の型を試すと、実行保護違反が発生し、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

では、これらの戻り値の型を取得するにはどうすればよいでしょうか? 特にストリング。

どんな助けでも大歓迎です。

4

1 に答える 1

1

最初に (String ではなく) Pointer を返し、次にさまざまな Pointer メソッドを使用して、それが指すメモリを調べることをお勧めします。関数が何を返すかを理解したら、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);
}

編集より最近のバージョンのパスカル ヘッダー ファイルを 参照すると、 Java タイプshortの forsmallIntおよびforを使用する必要があります。ただし、これらのタイプに切り替えても完全な修正にはなりません (スタックの破損が減少します - 間違ったフラグで DB を「開いている」ことになります)。WordBoolintLong

于 2012-09-04T14:23:49.007 に答える