Java NativeCall 库返回数据类型

标签 java dll jna

我目前正在尝试使用 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 函数的函数声明,该函数从当前记录中获取字符串字段。 声明函数 sx_GetString Lib "sde32.dll"(ByVal cpFieldName As String) As String

如何将此信息导入 Java?似乎只有 int (和 boolean)和 void 返回类型,我怎样才能返回 String、double 和 long 类型?

使用 JNA,我似乎可以访问 double 和长整型数,但是当我尝试字符串返回类型时,我遇到了执行保护冲突,并且 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 错误:

违反执行保护

#

# Java 运行时环境检测到 fatal error :

#

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

那么我怎样才能获得这些返回类型呢?特别是字符串。

任何帮助将不胜感激。

最佳答案

我建议首先返回一个指针(而不是字符串),然后使用各种指针方法来检查它指向的内存。一旦了解了函数返回的内容,您就可以弄清楚如何使 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对于更新的版本,您应该对 smallIntWordBool 使用 Java 类型 short,对 int 使用 int 。但是,切换到这些类型并不能提供完整的修复(它将减少堆栈损坏 - 您将使用错误的标志“打开”数据库)。

关于Java NativeCall 库返回数据类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12241009/

相关文章:

java - 为什么继承每个类然后简单地创建派生类的单个对象来执行 oop 中的所有操作是一种不好的做法?

java - SwarmCache Hibernate 配置

c# - 如何从浏览器调用 WCF 服务 OperationContract?

visual-studio - VC2013 错误 MSPDB120.DLL

Java JNA - 基址查找

java - 使用Java访问第三方DLL

java - 使用 SBT 的 Jetty 和 Scala 部署策略?

Java Webstart 尝试将 jar 沙箱化为 "Trusted-Library"

c# - 从 C# 调用 C DLL

java - 在 Netbeans 中加载 DLL