前段时间,公司做的项目需要调用动态so库文件,经研究后,决定采用jna技术。
开始定义一个结构体如下:
public class SecureStruct extends Structure {
public String sk;
public String srcDase64Data;
public int srcLen;
public String resBase64Data;
public int resLen;
protected List<String> getFieldOrder() {
List tmpLis = new ArrayList();
tmpLis.add("sk");
tmpLis.add("srcDase64Data");
tmpLis.add("srcLen");
tmpLis.add("resBase64Data");
tmpLis.add("resLen");
return tmpLis;
}
public void freeMemory() {
try {
resBase64Data = null;
sk = null;
srcDase64Data = null;
this.finalize();
} catch (Throwable e) {
e.printStackTrace();
}
}
}
jna 接口:
public interface JnaService extends Library {
/**
* 加密接口
* @param struct
* @return
*/
int symmEncryptData(SecureStruct struct);
/**
* 解密接口
* @param struct
* @return
*/
int symmDecryptData(SecureStruct struct);
}
调用代码:
SecureStruct struct = (SecureStruct) Structure.newInstance(SecureStruct.class);
JnaService().symmCleanData(struct);
注意问题来了,结构是new 出来的。每调用一次就要new一次。结构传入动态库so文件后,java垃圾回收机制是不会回收该对象的,随着调用的次数不断增加,内存结构体对象越来越多,最终会造成内存崩溃。
解决办法:
别传对象了,so动态库也不要申请内存,由jna申请好,以供so使用。核心代码如下:
int size = data.length + 1024 * 512;
Pointer out = new Memory(size);
long peer = Pointer.nativeValue(out);
IntByReference outLen = new IntByReference();
jnaService.jnaSymmEncryptData(data, data.length, sk, sk.length, out, outLen);
resDatas = out.getByteArray(0, outLen.getValue());
System.out.println("------------口返回的长度------------" + outLen.getValue());
Native.free(peer);
Pointer.nativeValue(out, 0);
这样每调用一次申请一次,用完就释放。
经测试,不会造成内存居高不下的问题。
分享到:
相关推荐
总结,Java调用DLL动态库主要依赖于JNA库,通过定义接口并加载库文件,能够直接调用DLL中的函数。在这个实例中,我们了解了如何设置环境,定义接口,以及如何加载和调用"NetSdk.dll"中的函数。这些知识对于需要与C++...
Java 使用 JNA(Java Native Access)调用C/C++编写的第三方动态库(DLL文件)是一种常见的技术,它允许Java程序直接与本地操作系统接口交互,而无需编写JNI(Java Native Interface)代码。JNA 提供了一种相对简洁...
本案例将详细介绍如何使用JNA来调用C++动态库,特别是处理二维数组的输入和输出。 首先,我们需要了解JNA的基本原理。JNA通过映射Java接口到本地函数,实现了跨语言调用。它提供了一个简洁的方式来定义C/C++函数...
Java Native Access(JNA)是一种开源的Java框架,它为Java程序员提供了一种简洁的方式来调用C动态库(如.dll、.ocx、.so),大大简化了原本繁琐的JNI(Java Native Interface)调用过程。JNA由SUN公司主导开发,它...
java获取dll动态库源码分享。通过jna加载动态库,然后初始化动态库,打开动态库,在通过指针获取动态库里面的数据。
在Linux环境下运行,你需要确保JNA库和编译好的C库(动态链接库.so)都在正确的位置,或者在Java代码中指定了正确的路径。此外,操作步骤文档应该详细指导如何编译C代码,打包Java项目,以及如何执行程序。 总结,...
JNA(Java Native Access )提供一组Java工具类用于在运行期动态访问系统本地库(native library:如Window的dll)而不需要编写任何Native/JNI代码。开发人员只要在一个java接口中描述目标native library的函数与...
Java JNA(Java Native Access)是一种在Java平台上与本地代码交互的库,允许开发者无需编写JNI(Java Native Interface)代码就能调用C、C++等本地库。本示例将详细解析如何使用JNA在Java中调用C语言库文件。 首先...
本项目涉及的"java调用C++动态链接库dll接口"是解决这种跨语言交互问题的一种方法,主要利用了Java Native Interface(JNA)这一技术。 JNA是Java平台的标准库,它允许Java代码直接调用本机库(如DLL或.so文件)的...
总结,通过上述步骤,我们成功地利用Java的JNI功能调用了由Delphi编译的动态库。这种跨语言的通信方式在需要利用特定语言特性或优化性能时非常有用。了解和掌握这一技巧,可以极大地扩展Java应用的能力,同时充分...
详细演示了如何通过JNA实现以下形式的动态链接库接口: 1:基本数据类型 2:基本数据类型的指针和引用 3:结构体 4:结构体的指针和引用 5:函数指针和回调函数 6:字符串指针 7:输入一个数组 8:输出一个数组并...
JNA(Java Native Access)是一个基于经典JNI技术的Java开源框架,它允许Java应用程序动态地访问本机库,例如Windows系统的.dll文件,而无需编写任何JNI或本机代码。通过在Java接口中描述目标本机库的功能和结构,...
在Java中使用JNA调用动态库通常涉及以下步骤: 1. **引入JNA库**:首先,你需要在项目中引入JNA库。可以通过Maven或Gradle等构建工具添加依赖。对于Maven,可以在pom.xml文件中添加以下依赖: ```xml <groupId>...
General_NetSDKDemo_Chn_...这里的包是Linux64最全的,大华技术说其他的linux动态库都是有问题的 分三个包 大华设备各种Demo及所需jar包 \libs\linux64 examples.jar IStreamConvertor.jar jna.jar 版本5.0好像
Java Native Access(JNA)是Java平台上的一个开源库,它允许Java代码直接与本地操作系统API交互,无需编写C语言的JNI(Java Native Interface)代码。JNA通过提供一种高级映射机制,使得开发者可以方便地调用本地...
Java使用JNA调用C动态库的方法,JNA提供一组Java工具类用于在运行期间动态访问系统本地库(native library:如Window的dll),只需要依赖一个jar包,而不需要编写任何Native/JNI代码,就像调用一个java方法一样简单...
在Java世界中,有时我们需要利用Java Native Interface (JNI) 和 Java Native Access (JNA) 这两种技术来调用C++编写的动态链接库(DLL或SO文件),以实现Java程序与底层系统的交互。这两者都是Java平台上的关键组件,...
研究java调用dll的时候,大部分都是通过jni,比较麻烦,我找到了通过jna方法调用dll的方法,用起来比较方便,只需要引用jna.jar包,这个jar包已经包含在程序中,还包含了我调用dll的遇到难道的解决办法。
在标题中提到的“JNA调用.dll文件或.so动态链接库的代码demo”,这是一个实际应用JNA来调用本地动态库的示例。下面我们将深入探讨JNA的工作原理、使用步骤以及如何处理.dll和.so文件。 1. **JNA工作原理**: JNA...
例如,如果开放平台提供了C/C++开发的二进制数据解析服务,且给出了相应的.h头文件,那么在Java中直接调用并解析这些数据可能会相当复杂且效率不高。 #### 解决方案概述 为了解决上述问题,一种常见的策略是请求C++...