大家好,
我有一个由其他部门的开发人员为Win32用C ++编写的非常复杂且很大的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);
}
查看基于Windows DLL的许多示例类型的JNA source code in the com.sun.jna.platform.win32
package。本质上,您为DLL做的是相同的事情。
在我的java进程中直接使用这些对象
com.sun.jna.platform.win32
也称为另外两个DLL,并从中广泛使用了数据
您需要类似地映射其他DLL(创建接口,使用ComplicatedAndBigLibrary CABL = ComplicatedAndBigLibrary.INSTANCE;
CABL.NiceFunction(foo, bar, ...)
并映射函数/常量/等。]