当前位置: 首页 > ai >正文

springboot项目读取dll

目录

  • 1. 依赖
  • 2. 代码
  • 3. 坑
    • %1 不是有效的 Win32 应用程序。

1. 依赖

        <dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><!-- 调用dll --><dependency><groupId>net.java.dev.jna</groupId><artifactId>jna</artifactId><version>5.12.1</version></dependency><!-- json转换 --><dependency><groupId>com.alibaba.fastjson2</groupId><artifactId>fastjson2</artifactId><version>2.0.35</version></dependency>

2. 代码

读取dll:

/*** @desc 调用 SSSE32.dll* @Date 2025/5/20 15:17*/
@Slf4j
@Service
public class BankTransServiceImpl implements BankTransService {@Resourceprivate YmlConfig ymlConfig;private static final int POINTER_BUFFER_SIZE = 512 * 512;@Overridepublic String callBankTrans(JSONObject params) {// 返参String res;String inputData = JSONObject.toJSONString(params);// 设置JNA编码System.setProperty("jna.encoding", ymlConfig.getDllEncode());// 设置内存保护模式是否开启System.setProperty("jna.protected", ymlConfig.getDllProtected());NativeLibrary nativeLibrary = NativeLibrary.getInstance(ymlConfig.getDllPath());// 声明内存操作相关变量Memory outMemory = null;    // 输出数据内存缓冲区Pointer inPointer = null;   // 输入数据指针Object[] inputArgs;         // 输入参数数组(用于业务调用)try {// 创建输出内存缓冲区(预分配空间)outMemory = createStrOutMemory();// 将输入字符串转换为指针(供DLL读取)inPointer = createStrInPointer(inputData);// 业务调用参数数组(输入指针+输出缓冲区)inputArgs = new Object[]{inPointer, outMemory};// 调用 dll 函数int rpcStatus = nativeLibrary.getFunction(ymlConfig.getFunctionName()).invokeInt(inputArgs);String outputData = readStrMemory(outMemory);BankTransResponse bankTransResponse;try {bankTransResponse = JSON.parseObject(outputData, BankTransResponse.class);} catch (Throwable e) {log.error("解析{}返回报文失败: {}", getFileName(ymlConfig.getDllPath()), e.getMessage());return ResultBean.fail("解析返回报文失败:" + e.getMessage() + ";rpcStatus=" + rpcStatus).toStringJSON();}if (!"00".equals(bankTransResponse.getRespCode())) {return ResultBean.fail("调用 " + ymlConfig.getFunctionName() + " 函数失败: " + bankTransResponse.getRespMsg()).toStringJSON();}res = ResultBean.success(bankTransResponse).toStringJSON();} catch (Exception e) {log.error("调用 {} 函数失败: {}", ymlConfig.getFunctionName(), e.getMessage());return ResultBean.fail("调用" + ymlConfig.getFunctionName() + "失败: " + e.getMessage()).toStringJSON();} finally {// 资源释放块(防止内存泄漏)if (Objects.nonNull(inPointer)) {inPointer = null;// 注:某些环境可能需要显式释放 Native.free()// freeMemory(inPointer);}if (Objects.nonNull(outMemory)) {// 置空输出内存outMemory = null;// freeMemory(outMemory);}if (Objects.nonNull(nativeLibrary)) {// 关闭DLL引用nativeLibrary.close();}}return res;}// region 下列是工具方法private static Memory createStrOutMemory() {Memory memory = new Memory(POINTER_BUFFER_SIZE);memory.clear();memory.setString(0, "");return memory;}private static Pointer createStrInPointer(String str) {Pointer pointer = new Memory(POINTER_BUFFER_SIZE);pointer.setString(0, str, System.getProperty("jna.encoding"));return pointer;}private static String readStrMemory(Memory memory) {String rtn = memory.getString(0, System.getProperty("jna.encoding")).trim();
/*        long peer = Pointer.nativeValue(memory);//手动释放内存Native.free(peer);Pointer.nativeValue(memory, 0);*/return rtn;}private static void freeMemory(Pointer pointer) {try {long peer = Pointer.nativeValue(pointer);//避免Memory对象被GC时重复执行Nativ.free()方法Native.free(peer);Pointer.nativeValue(pointer, 0);//手动释放内存} catch (Throwable t) {log.error("清内存失败: {}", t.getMessage())}}private static String getFileName(String path) {if (path == null || path.isEmpty()) {return "";}// 替换路径分隔符,统一为正斜杠path = path.replace("\\", "/");// 获取最后一个斜杠的位置int lastSlashIndex = path.lastIndexOf('/');// 如果路径中没有斜杠,直接返回路径本身if (lastSlashIndex == -1) {return "";}// 返回最后一个斜杠之后的部分,即文件名return path.substring(lastSlashIndex + 1);}// endregion
}

ResultBean:

/*** @desc ResultBean* @Date 2025/5/20 15:59*/
@Data
@NoArgsConstructor
@AllArgsConstructor
@Accessors(chain = true)
public class ResultBean<T> {public static final int SUCCESS = 1;public static final int FAIL = -1;private int code = SUCCESS;private String message = "success";private transient T data;public ResultBean(T data){super();this.data = data;}public ResultBean(int code, String message) {this.code = code;this.message = message;}public boolean isSuccess() {return SUCCESS == this.code;}public static <T> ResultBean<T> success(T data) {return new ResultBean<>(data);}public static <T> ResultBean<T> fail(String message) {return new ResultBean<>(FAIL, message);}/*** @desc    存在data的泛型数据类型,无法被 jsonObject 转化成 jsonString* @param* @return  java.lang.String* @date    2025/5/20 16:03**/public String toStringJSON() {return "{\"code\":" +code +"," +"\"message\":" +"\"" + message + "\"" +"," +"\"success\":" +"\"" + isSuccess() + "\"" +"," +"\"data\":" +JSONObject.toJSONString(data) +"}";}
}

3. 坑

%1 不是有效的 Win32 应用程序。

NativeLibrary.getInstance(ymlConfig.getDllPath()); 报错:

2025-05-20 16:17:08.880 [45249010-d03a-4eeb-b7bf-a18311fdd77a] [http-nio-9091-exec-1] ERROR o.a.c.c.C.[.[.[/fsiutil].[dispatcherServlet] - Servlet.service() for servlet [dispatcherServlet] in context with path [/fsiutil] threw exception [Handler dispatch failed; nested exception is java.lang.UnsatisfiedLinkError: Unable to load library 'C:\Users\Lenovo\Desktop\CQSecurityCardDemo\SSSE32.dll':
%1 不是有效的 Win32 应用程序。%1 不是有效的 Win32 应用程序

错因: DLL与JVM位数不一致

32位DLL → 32位JVM
64位DLL → 64位JVM

处理: 下载一个32位的JDK,不配置环境变量,idea直接指定使用该jdk。

  1. 下载:https://mirrors.tuna.tsinghua.edu.cn/Adoptium/8/jdk/x32/windows/

  2. idea指定jdk

http://www.xdnf.cn/news/7749.html

相关文章:

  • RT_Thread——快速入门
  • 电子电路:怎么理解放大电路中集电极电流Ic漂移?
  • 如何使用Java生成pdf报告
  • 面向恶劣条件的道路交通目标检测----大创自用(当然你也可以在里面学到很多东西)
  • 如何使用AI搭建WordPress网站
  • SAP-ABAP:ABAP异常处理与安全工程的融合 —— 构建防注入、防泄漏、合规审计的防御性编程体系
  • C# Prism框架详解:构建模块化WPF应用程序
  • 轩辕杯Wp
  • 【Java】泛型在 Java 中是怎样实现的?
  • java day14
  • debian系统redis-dump安装
  • Vite + Vue 工程中,为什么需要关注 `postcss.config.ts`?
  • 如何用JAVA手写一个Tomcat
  • c#基础03(运算符)
  • LeetCode 3355.零数组变换 I:差分数组
  • 34、React Server Actions深度解析
  • 07 接口自动化-用例管理框架之pytest单元测试框架
  • CSS:margin的塌陷与合并问题
  • 每日Prompt:实物与手绘涂鸦创意广告
  • MySQL5.7导入MySQL8.0的文件不成功
  • flutter 常用组件详细介绍、屏幕适配方案
  • GPU加速Kubernetes集群助力音视频转码与AI工作负载扩展
  • PostgreSQL使用
  • Canvas进阶篇:鼠标交互动画
  • Java 安全SPEL 表达式SSTI 模版注入XXEJDBCMyBatis 注入
  • 2025年渗透测试面试题总结-快手[实习]安全工程师(题目+回答)
  • ToDesk云电脑、并行智算云与顺网云AI支持能力深度实测报告
  • 25、工业防火墙 - 工控网络保护 (模拟) - /安全与维护组件/industrial-firewall-dcs-protection
  • 遨游科普:三防平板有哪些品牌?哪个品牌值得推荐?
  • tomcat知识点