多平台统一管理软件接口,如何实现多平台统一管理软件接口
801
2022-08-28
Java调用dll文件的实现解析
目录java调用dll文件环境接下来进入正文Java调用dll文件几种常见方式Java调用动态库需要关注的问题一.数据类型对应关系二.Jnative调用dll三.JNA调用dll
Java调用dll文件
近期根据C++做了一个图片质量检测的项目,目前需要在在java中进行调用,所以先在C++上生成dll文件,然后基于java调用dll文件实现功能。
环境
C++:VS2017(之前配置opencv真是要了老命)
java:idea2020+jdk1.8。
注意:jdk安装的时候小心点,path路径容易点编辑,千万别新建,会覆盖的。
接下来进入正文
1. 创建Java项目,假设定义HelloWorld函数,其中“winproject1”是等会要调用的dll文件,现在进入cmd并cd到当前目录下面,然后javah -jni HelloWorld.HelloWorld,这样会在目录下面生成一个HelloWorld_HelloWorld.h。
等会需要将这个头文件移到之前安装jdk目录里的include下面,如:D:%你的路径%\Java\include。
2. 打开vs2017,创建一下新的控制台项目,然后需要配置项目包含目录的路径,将下面两个路径加进去,保险点还可以在附加目录里面加上这些路径。http://
vs2017中编写上面头文件中的代码:
JNIEXPORT void JNICALL Java_HelloWorld_HelloWorld_sayHello (JNIEnv *, jobject, jstring, jstring, jstring, jstring) { cout<<"hello world!"< **注:**其中#include "single_check.h"就是我定义检测函数的头文件,在下面的函数中可以调用自己定义的函数,从而让java执行里面的内容,可以调用函数。 3.生成第一步中提到的winproject1.dll文件,直http://接点击生成-生成解决方案,便可以在项目路径(%项目名%\x64\Debug\winproject1.dll)中找到dll文件,并且复制到jdk安装路径的bin文件夹下(D:%你的路径%\Java\bin\) 4.最后一步最简单啦,在java里面直接run就行啦。最后看一下结果!完美! 这是windows下用java调用dll文件,接下来要实现跨平台调用,得在linux下用java可以实现改功能。头秃啊 Java调用dll文件几种常见方式 Java调用动态库需要关注的问题 1.如何装载DLL文件,以及如何定位所要使用的方法; 2.数据类型如何对应; 3.如何给使用的方法传递参数; 4.如何获取返回的值。 一.数据类型对应关系 Java TypeC Typebooleanintbytecharcharwchar_tshortshortdoubledoublefloatfloatStringchar* 二.Jnative调用dll Jnative是对JNI技术进行了封装,更加方便的让java去调用DLL。 1. 下载Jnative库,其中包含JNative.jar, JNativeCPP.dll, JNativeCPP.so这三个包。 JNative.jar是需要导入到Java工程的lib下, JNativeCPP.dll文件放在jdk安装目录下,或者是user\System32目录下,或者项目根目录下。 2. 将需要调用的dll动态链接库放在SYSTEM32文件夹下,或者是项目根目录下,否则会出现找不到dll文件的错误。 3. 加载DLL库 : System.loadLibrary("TranferEth"); // TransferEth为需要调用的DLL文件,只需要使用DLL文件的文件名即可。 4. 调用DLL入口函数 : JNative jnt = new JNative("TransferEth.dll", "Transfer_Ethernet"); // 参数1为需要调用的DLL文件, 参数2为需要调用的方法。 5. 设置返回参数类型 : jnt.setValhttp://(Type.INT); 6. 设置传入参数 : jnt.setParameter(0, "TransferScale.ini"); 7. 执行调用 : jnt.invoke(); 8. 释放资源 : jnt.dispose(); 三.JNA调用dll JJNA中,它提供了一个动态的C语言编写的转发器,可以自动实现Java和C的数据类型映射。你不再需要编写C动态链接库。 1.在java项目中引入jna.jar。 (当前引用的版本为3.4.0 , 之前的版本未提供释放动态链接库资源的方法) 2.定义调用接口, 接口方法与需要调用的DLL提供的外部函数一致。 例如:DLL文件中提供入口函数: extern "C" __declspec(dllexport) UINT __stdcall Transfer_Ethernet_EX(char *cTransScale , int nKey); extern "C" __declspec(dllexport) UINT __stdcall Transfer_Ethernet(char *cTransScale ); 则定义的接口类中如下: (数据类型对应关系如上) public interface CallMTScaleLibrary extends Library { public int Transfer_Ethernet_EX(String filename, int key); public int Transfer_Ethernet(String filename); } 3.加载DLL文件 String dir = path + "dllName"; // dll文件的路径,可以省略后缀名,dll和so后缀都可以加载 CallMTScaleLibrary scaleLibrary = (CallMTScaleLibrary) Native.loadLibrary(dir, CallMTScaleLibrary.class); 4.执行调用 int result = scaleLibrary.Transfer_Ethernet(path + "TransferScale.ini"); 5.释放资源 一次调用完成后需要释放掉资源,以便后续重复调用该资源。通过查看jna的源码Native类中有私有方法dispose()可以主动释放掉资源,可以通过反射的方式去调用该方法,也可以重写该方法,从而实现释放。 private static void dispose(){ NativeLibrary.disposeAll(); nativeLibraryPath = null; } 注意问题: 1.文件路径:DLL文件最好放在项目的根目录下,或者是system32文件夹下,必须在环境变量配置的path中。 2.循环调用:当循环调用同一个DLL文件时,必须要释放掉上一次的资源,否则会被占用端口(每次调用都会在线程里进行一次网络通讯)。
**注:**其中#include "single_check.h"就是我定义检测函数的头文件,在下面的函数中可以调用自己定义的函数,从而让java执行里面的内容,可以调用函数。
3.生成第一步中提到的winproject1.dll文件,直http://接点击生成-生成解决方案,便可以在项目路径(%项目名%\x64\Debug\winproject1.dll)中找到dll文件,并且复制到jdk安装路径的bin文件夹下(D:%你的路径%\Java\bin\)
4.最后一步最简单啦,在java里面直接run就行啦。最后看一下结果!完美!
这是windows下用java调用dll文件,接下来要实现跨平台调用,得在linux下用java可以实现改功能。头秃啊
Java调用dll文件几种常见方式
Java调用动态库需要关注的问题
1.如何装载DLL文件,以及如何定位所要使用的方法;
2.数据类型如何对应;
3.如何给使用的方法传递参数;
4.如何获取返回的值。
一.数据类型对应关系
Java TypeC Typebooleanintbytecharcharwchar_tshortshortdoubledoublefloatfloatStringchar*
二.Jnative调用dll
Jnative是对JNI技术进行了封装,更加方便的让java去调用DLL。
1. 下载Jnative库,其中包含JNative.jar, JNativeCPP.dll, JNativeCPP.so这三个包。 JNative.jar是需要导入到Java工程的lib下, JNativeCPP.dll文件放在jdk安装目录下,或者是user\System32目录下,或者项目根目录下。
2. 将需要调用的dll动态链接库放在SYSTEM32文件夹下,或者是项目根目录下,否则会出现找不到dll文件的错误。
3. 加载DLL库 : System.loadLibrary("TranferEth"); // TransferEth为需要调用的DLL文件,只需要使用DLL文件的文件名即可。
4. 调用DLL入口函数 : JNative jnt = new JNative("TransferEth.dll", "Transfer_Ethernet"); // 参数1为需要调用的DLL文件, 参数2为需要调用的方法。
5. 设置返回参数类型 : jnt.setValhttp://(Type.INT);
6. 设置传入参数 : jnt.setParameter(0, "TransferScale.ini");
7. 执行调用 : jnt.invoke();
8. 释放资源 : jnt.dispose();
三.JNA调用dll
JJNA中,它提供了一个动态的C语言编写的转发器,可以自动实现Java和C的数据类型映射。你不再需要编写C动态链接库。
1.在java项目中引入jna.jar。 (当前引用的版本为3.4.0 , 之前的版本未提供释放动态链接库资源的方法)
2.定义调用接口, 接口方法与需要调用的DLL提供的外部函数一致。
例如:DLL文件中提供入口函数:
extern "C" __declspec(dllexport) UINT __stdcall Transfer_Ethernet_EX(char *cTransScale , int nKey);
extern "C" __declspec(dllexport) UINT __stdcall Transfer_Ethernet(char *cTransScale );
则定义的接口类中如下: (数据类型对应关系如上)
public interface CallMTScaleLibrary extends Library {
public int Transfer_Ethernet_EX(String filename, int key);
public int Transfer_Ethernet(String filename);
}
3.加载DLL文件
String dir = path + "dllName"; // dll文件的路径,可以省略后缀名,dll和so后缀都可以加载
CallMTScaleLibrary scaleLibrary = (CallMTScaleLibrary) Native.loadLibrary(dir, CallMTScaleLibrary.class);
4.执行调用
int result = scaleLibrary.Transfer_Ethernet(path + "TransferScale.ini");
5.释放资源
一次调用完成后需要释放掉资源,以便后续重复调用该资源。通过查看jna的源码Native类中有私有方法dispose()可以主动释放掉资源,可以通过反射的方式去调用该方法,也可以重写该方法,从而实现释放。
private static void dispose(){
NativeLibrary.disposeAll();
nativeLibraryPath = null;
}
注意问题:
1.文件路径:DLL文件最好放在项目的根目录下,或者是system32文件夹下,必须在环境变量配置的path中。
2.循环调用:当循环调用同一个DLL文件时,必须要释放掉上一次的资源,否则会被占用端口(每次调用都会在线程里进行一次网络通讯)。
版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。
发表评论
暂时没有评论,来抢沙发吧~