我们正在尝试开发一个加载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)
答案 0 :(得分:1)
您的DLL正在导出C ++ - 损坏的名称。 DLL导出会为您解除它们。如果使用a different viewer检查DLL,则应该看到原始名称。
如果要以非破坏方式导出名称,则需要在给定的函数声明中使用extern "C"
装饰器。这通常只适用于静态方法(不是类方法)。
但是,这只是您问题的一部分。如果要将Java类直接映射到C ++类,则需要使用类似SWIG的内容并编译一些本机粘合代码。