java 调用 dll动态库

检查dll动态库

通过软件 DependenciesGui.exe 检查CloseLoopCalDll.dll动态库

  • 动态库缺少依赖

image.png

注意点:缺陷dll核心依赖,加载的时候会报错缺少依赖,如果是Windows系统依赖缺失并且dll算法并没有调用此依赖时,是可以加载成功的

  • 动态库打包错误

a6e11f8770841085082ad00c0eca430.png

注意点:dll虽然可以成功加载,但是由于动态库的打包错误,相应的方法是找不到。

  • 正确的动态库

image.png

java程序加载dll动态库

  • 导入依赖
//jna
implementation group: 'net.java.dev.jna', name: 'jna'
  • 按路径加载
  private static void loadFile(String ext,File file){
        if (ext.equals(".so") || ext.equals(".dll")) {
            try {
                System.load(file.getPath());
                log.info("加载native文件[{}]成功!!", file);
            } catch (UnsatisfiedLinkError e) {
                log.error("加载native文件[{}]失败!!请确认操作系统是否能解析文件", file);
            }
        }
    }
  • 按文件名加载
 private static void loadFile(String ext,File file){
        if (ext.equals(".so") || ext.equals(".dll")) {
            try {
                System.loadLibrary(file.getName());
                log.info("加载native文件[{}]成功!!", file);
            } catch (UnsatisfiedLinkError e) {
                log.error("加载native文件[{}]失败!!请确认操作系统是否能解析文件", file);
            }
        }
    }

注意点:加载dll动态库可以自己创建类和方法去实现

调用dll动态库

  • 创建接口类
public interface CloseLoopCal extends Library {}

注意点:接口类需要继承 Library 类

  • 编写java 抽象方法
boolean SafeAnalysis(double[] result,byte[] data,int count,double[] parameter,  String filePath);
  • 与其对应的c++方法
bool SafeAnalysis(double *result, char *data, int count, double *parameter, char *fname);
  • 基本数据类型映射关系

  • 调用dll动态库
//很关键 设置字符集,字符集不匹配无法调用dll
System.setProperty("jna.encoding", "GB2312");
Native.setProtected(true);
CloseLoopCal closeLoopCal = Native.loadLibrary("CloseLoopCalDll", CloseLoopCal.class);
closeLoopCal.SafeAnalysis(new double[10],new byte[10],5,new double[10],"");

注意点:字符集的类型和调用dll字符集类型必须保持一致

生产环境运行

生产环境下和测试环境下略有不同,测试环境下我们只需要把dll放到项目根目录即可加载dll,生产环境运行的是jar包,dll可能没有一起打包,会导致找不到dll的问题,网上解决办法比较多,自行解决。
end

评论