通过 JNA 从具有大量 类 的非常复杂的 C++ Win32 DLL 调用方法 Java 进程

Call methods from a very complicated C++ Win32 DLL with tons of classes by Java process via JNA

我有一个由其他部门的开发人员用 C++ 为 Win32 编写的非常复杂和大的 DLL,我的 java- 进程需要使用它。我有:

限制:我不允许(尽管我有一个 .sol 文件)对该 DLL 进行任何更改。

目标: 我希望我的 java-进程能够从这个 DLL 中调用一些方法。

仪器: 首先我想用 JNA(第二个 witn JNI)试试。

问题:

我阅读了一些有关 JNA 的一般信息并了解到,首先要构建要在接口中调用的方法的原型。好,现在的问题是:我要调用的方法,以DLL工程中的自定义对象为参数。例如,我在 DLL 中有一个函数,如:

__declspec(dllexport) BOOL WINAPI NiceFunction( 
          Dummy_State *ModuleState, Dummy_Handle Handle, Dummy_Exception &Exception,
          LPCTSTR name, DWORD timer);

其中所有 Dummy_ 对象都是 class 对象,在此 DLL 中定义。

问题1:如何在我的java进程中用JNA调用这样的函数?

问题 2: 是否可以在我的 java 过程中以某种方式直接使用这些对象?也许以某种方式导入构造函数?但是,这些对象的构造函数通常需要调用父对象 class(es).

的构造函数

问题 3: 最后但同样重要的是,我的 DLL 还调用了两个额外的 DLL 并广泛使用了它们的数据(Dummy_ 对象中的一些)。我是否还需要(以某种方式)通过 JNA 在我的 java 进程中导入它们?

JNA 仅适用于 C 函数,不适用于 C++。您能够映射的唯一 C++ 函数必须已使用 extern "C" 外部化。如果它们不是,并且您无法更改 DLL,您可能必须编写自己的 DLL 包装器,该包装器具有 extern "C" 个版本。

如何用JNA调用这样的函数:

您必须将它们映射到 Java 接口。例如:

public interface ComplicatedAndBigLibrary {
    // Create an instance to access the mapped functions with
    // the String in quotes is the filename, minus .dll
    ComplicatedAndBigLibrary INSTANCE = 
        (ComplicatedAndBigLibrary) Native.load("compbiglib", W32APIOptions.DEFAULT_OPTIONS);

    // Map the C structures or typedefs
    // Use "extends" as needed for parents
    @FieldOrder({"field1", "field2"})
    class Dummy_State extends Structure {
        // map structure fields here
        public int field1;
        public byte field2;
    }

    class Dummy_Handle extends WinNT.HANDLE {
        // any overrides you need
    }

    // Map your functions (that were externalized)
    boolean NiceFunction( 
          Dummy_State ModuleState, Dummy_Handle Handle, Dummy_Exception ExceptionPointer,
          LPCTSTR name, DWORD timer);
}

查看 JNA source code in the com.sun.jna.platform.win32 package,了解许多基于 Windows DLL 的示例。您实际上是在为您的 DLL 做同样的事情。

以某种方式直接在我的 java 过程中使用这些对象

ComplicatedAndBigLibrary CABL = ComplicatedAndBigLibrary.INSTANCE;
CABL.NiceFunction(foo, bar, ...)

还调用了两个额外的 DLL 并广泛使用了它们的数据

您需要以类似方式映射其他 DLL(创建接口,使用 Native.load() 并映射 functions/constants/etc。)