通过 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。)
我有一个由其他部门的开发人员用 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。)