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

DLL export viewer shows full signatures of functions - unable to call them from Java

本文关键字:Java 调用 显示 函数 DLL      更新时间:2023-10-16

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

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

不起作用的DLL的导出视图

我们已经尝试创建一些示例DLL并将它们加载到Java中,我们取得了成功。可见的区别在于,当我们将创建的这些DLL加载到"DLL导出查看器"中时,我们看到了没有完整签名(只有名称)的函数:

我们创建的DLL,使用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)

您的DLL正在导出C++损坏的名称。DLL导出正在为您卸载它们。如果使用不同的查看器检查DLL,则应该看到原始名称。

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

然而,这只是你问题的一部分。如果您想直接将Java类映射到C++类上,您需要使用类似SWIG的东西并编译一些本地的粘合代码。