DLL导出查看器显示函数的完整签名-无法从Java调用它们
DLL export viewer shows full signatures of functions - unable to call them from Java
我们正在尝试开发一个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的东西并编译一些本地的粘合代码。
相关文章:
- 如何从 Java 调用C++函数?
- Java 调用 dll 字符串返回类型方法
- JNI_OnLoad获取 Java 调用方包 + 类名
- 在 android 上从 Java 调用C++类方法或函数,而无需在每次调用时重新创建类/变量
- 字符串在从Android Java调用ndk c ++函数后会得到一个奇怪的形式
- Java 调用的 C++ 内存泄漏
- 从 Java 调用C++函数
- 从java调用本机方法时使用Libc SIGSEGV
- 如何实现从 Java 调用C++的回调函数
- 使用JNI从Java调用本机(C++)函数时发生访问冲突:这是我的代码问题,还是已知问题
- 从 Java 调用C++函数。映射"const char*"
- 从 Java 调用 c++,然后从相同的 c++ 方法调用 java 方法
- 从JAVA调用C++可执行文件
- 如何使用JNI用java调用Scanner API的C方法
- 如何使用QAndroidJniObject从Java调用Intent
- 在Windows中使用swig从Java调用c ++函数,得到java.lang.UnsatisfiedLinkErro
- 你能不能使用 JNI 在从 java 调用的 c++ 函数中创建一个新的 JVM
- 从Java调用WinMain:可能吗?任何其他方式
- 从Android Java调用本机函数 - JNI的替代品
- Sudo Java调用C应用程序和权限