我目前正在尝试使用Java中的NTX索引访问DBF。我有很多年前的Artemis引擎(现在为ApolloDB)的副本,可以在VB6中完成此工作。它主要使用3个DLL SDE32.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。
我发现的问题是,某些功能(例如某些数据访问功能)会返回字符串,例如VB6中sx_GetString函数的函数声明,该函数从当前记录中获取字符串字段。
Declare Function sx_GetString Lib "sde32.dll" (ByVal cpFieldName As String) As String
如何将这些信息导入Java?似乎只有int(和boolean)和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
那么如何获得这些返回类型?特别是字符串。
非常感激任何的帮助。
最佳答案
我建议先返回一个Pointer(而不是String),然后使用各种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);
}
编辑
对于最新版本,请参考pascal header files,对于
short
和smallInt
,应使用Java类型WordBool
,对于int
,应使用Long
。但是,切换到这些类型并不能提供完整的解决方案(它将减少堆栈损坏-您将使用错误的标志“打开”数据库)。