简体   繁体   English

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

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

We are trying to develop a Java application that loads a DLL (written in C++) and uses its functions.我们正在尝试开发一个加载 DLL(用 C++ 编写)并使用其函数的 Java 应用程序。

When opening this DLL in "DLL Export Viewer" we can see the full signature of the functions exported, unlike any other DLL we load into the viewer:在“DLL 导出查看器”中打开此 DLL 时,我们可以看到导出函数的完整签名,这与我们加载到查看器中的任何其他 DLL 不同:

Exported view of the DLL that doesn't work无效的 DLL 的导出视图

We have tried to create some sample DLLs and load them to Java, and we were successful.我们尝试创建一些示例 DLL 并将它们加载到 Java,我们成功了。 The visibile difference was that when we loaded these DLLs we created into "DLL Export Viewer", we saw the functions without full signatures (only names):明显的区别是,当我们将这些我们创建的 DLL 加载到“DLL 导出查看器”中时,我们看到了没有完整签名(只有名称)的函数:

DLL We created, works from Java我们创建的 DLL,从 Java 工作

The code we use to load the DLL from Java is using JNA, and looks like this:我们用来从 Java 加载 DLL 的代码使用的是 JNA,如下所示:

Declaring an interface that mathces the DLL functions:声明一个对 DLL 函数进行数学运算的接口:

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

Loading it and calling its functions:加载它并调用它的函数:

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

    System.out.println("done");

}

Only when trying to load the DLL shown in the first image, we can't call any function and we always get the following error:只有在尝试加载第一个图像中显示的 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)

Your DLL is exporting C++-mangled names.您的 DLL 正在导出 C++ 错误的名称。 The DLL export is un-mangling them for you. DLL 导出正在为您处理它们。 If you examine the DLL with a different viewer , you should see the raw names instead.如果您使用不同的查看器检查 DLL,您应该看到原始名称。

If you want to export the names in a non-mangled manner, you need to use the extern "C" decorator on a given function declaration.如果您想以非修饰方式导出名称,则需要在给定的函数声明中使用extern "C"装饰器。 This generally will only work for static methods (not class methods).这通常仅适用于静态方法(不适用于类方法)。

However, this is only part of your problem.然而,这只是您问题的一部分。 If you want to directly map Java classes onto C++ classes, you'll need to use something like SWIG and compile some native glue code.如果您想直接将 Java 类映射到 C++ 类,则需要使用SWIG 之类的东西并编译一些本机粘合代码。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM