java - Java 进程通过 JNA 从一个非常复杂的 C++ Win32 DLL 调用方法,其中包含大量类
问题描述
我有一个由其他部门的开发人员用 C++ 为 Win32 编写的非常复杂且大的 DLL,我的 java 进程需要使用它。我有的:
限制:我不允许(尽管我有一个 .sol 文件)对该 DLL 进行任何更改。
目标:我希望我的 java 进程能够从这个 DLL 调用一些方法。
Instruments:首先我想用 JNA(第二个和 JNI)来试试。
问题:
我阅读了一些有关 JNA 的一般信息并理解,首先您要构建要在接口中调用的方法的原型。好的,现在的问题如下:我要调用的方法,将DLL项目中的自定义对象作为参数。例如,我在 DLL 中有一个函数,例如:
__declspec(dllexport) BOOL WINAPI NiceFunction(
Dummy_State *ModuleState, Dummy_Handle Handle, Dummy_Exception &Exception,
LPCTSTR name, DWORD timer);
所有Dummy_
对象都属于类,在此 DLL 中定义。
问题1:如何在我的java进程中用JNA调用这样的函数?
问题 2:是否可以在我的 java 进程中以某种方式直接使用这些对象?也许以某种方式导入构造函数?然而,这些对象的构造函数经常需要调用父类的构造函数。
问题 3:最后但同样重要的是,我的 DLL 还调用了两个额外的 DLL,并广泛使用了来自它们的数据(一些Dummy_
对象)。我是否还需要通过 JNA 在我的 java 进程中导入(以某种方式)它们?
解决方案
JNA 仅适用于 C 函数,不适用于 C++。您可以映射的唯一 C++ 函数必须已使用extern "C"
. 如果它们不是,并且您无法更改 DLL,则可能必须编写自己的具有extern "C"
版本的 DLL 包装器。
如何使用 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源代码,com.sun.jna.platform.win32
了解基于 Windows DLL 的多种类型的示例。您实际上是在为您的 DLL 做同样的事情。
在我的 java 进程中以某种方式直接使用这些对象
ComplicatedAndBigLibrary CABL = ComplicatedAndBigLibrary.INSTANCE;
CABL.NiceFunction(foo, bar, ...)
也称为两个额外的 DLL,并广泛使用来自它们的数据
您需要类似地映射其他 DLL(创建接口,使用Native.load()
和映射函数/常量/等)
推荐阅读
- python - Python中的守护线程与守护进程
- openedx - 更改 OpenEdx 密码恢复电子邮件中的徽标
- logging - Kafka lib用作Keycloak模块时如何停止Kafka DEBUG日志
- ruby - 命名 Ruby 类和将其包装在模块中有什么区别?
- python - TypeError:无法使用 Sympy 将表达式转换为浮点数
- r - 将列中所有项目的平方添加为R数据框中的一行
- reactjs - 覆盖材质 UI 按钮文本
- jenkins-groovy - 接收 CS0234:使用 MSBuild.exe 的命名空间“Microsoft”中不存在类型或命名空间名称“VisualStudio”
- angular - Froala 编辑器 formControl 在第二次加载后未更新
- mysql - MariaDB存储过程产生不清楚的错误,怎么回事?