DLL导出查看器显示函数的完整签名 - 无法从Java调用它们

时间:2015-11-02 13:06:37

标签: java c++ dll jna

我们正在尝试开发一个加载DLL(用C ++编写)并使用其功能的Java应用程序。

在" DLL导出查看器"中打开此DLL时我们可以看到导出函数的完整签名,与我们加载到查看器中的任何其他DLL不同:

Exported view of the DLL that doesn't work

我们尝试创建一些示例DLL并将它们加载到Java,我们成功了。可见差异在于,当我们将这些DLL加载到" DLL Export Viewer"时,我们看到了没有完整签名的函数(只有名称):

DLL We created, works from Java

我们用来从Java加载DLL的代码使用的是JNA,如下所示:

声明一个算术DLL函数的接口:

public interface Ariel extends Library {
   Ariel INSTANCE = (Ariel) Native.loadLibrary("ariel", Ariel.class);
   void _ZN5ArielC1Ev();
   int _ZN5Ariel8getArielEv();
}

加载并调用其功能:

public static void main(String[] args) {
    Ariel ariel = Ariel.INSTANCE;
    ariel._ZN5ArielC1Ev();

    System.out.println("done");

}

只有在尝试加载第一张图片中显示的DLL时,我们才能调用任何函数,并且我们始终会收到以下错误:

Exception in thread "main" java.lang.UnsatisfiedLinkError: Error looking up function 'resetScale': The specified procedure could not be found.

at com.sun.jna.Function.<init>(Function.java:208)
at com.sun.jna.NativeLibrary.getFunction(NativeLibrary.java:536)
at com.sun.jna.NativeLibrary.getFunction(NativeLibrary.java:513)
at com.sun.jna.NativeLibrary.getFunction(NativeLibrary.java:499)
at com.sun.jna.Library$Handler.invoke(Library.java:199)
at com.sun.proxy.$Proxy0.resetScale(Unknown Source)
at Bolet.main(Bolet.java:6)

1 个答案:

答案 0 :(得分:1)

您的DLL正在导出C ++ - 损坏的名称。 DLL导出会为您解除它们。如果使用a different viewer检查DLL,则应该看到原始名称。

如果要以非破坏方式导出名称,则需要在给定的函数声明中使用extern "C"装饰器。这通常只适用于静态方法(不是类方法)。

但是,这只是您问题的一部分。如果要将Java类直接映射到C ++类,则需要使用类似SWIG的内容并编译一些本机粘合代码。