JNA 调用c++ 编译的so文件,传入指针释放内存

需求

java端要调用C++的接口,返回一个byte[]数据。

C++方法定义

DRESULT requestServerRoute(char* bufIn,unsigned int bufLengthIn,char** bufOut,unsigned int* bufLengthOut);

DRESULT releaseServerRouteResult(char* pos); 

方法1中,前两参数为输入参数,后两个为输出参数

方法1中为输出的数组申请了内存,方法2为释放此内存的方法,参数为方法1中 char** bufOut的指针
 

方法一正常调用,接收返回值。

byte[] bufIn = new byte[]{.....};

PointerByReference bufOut = new PointerByReference(Pointer.NULL);

IntByReference bufLengthOut = new IntByReference();

int requestServerRoute(bufIn, bufIn.length,bufOut,bufLengthOut);

byte[] data = bufOut.getValue().getByteArray(0, bufLengthOut.getValue());

问题在方法二,需要传递指向内存地址的指针

尝试1

传入bufOut.getPointer()

long addr1 = VM.current().addressOf(bufOut.getPointer()); //address

尝试2

传入bufOut.getValue()

long addr1 = VM.current().addressOf(bufOut.getValue()); //address

打印地址值和C++申请的地址做比较发现,都不对。。

也不知道jna如何应对这种情况,即将放弃,改用回调方式获取时,看到Pointer的源码中有个属性

/**Pointer value of the real native pointer. Use long to be 64-bit safe.
*/
protected long peer;

找到native pointer后,发现没有获取的方法,翻了一遍还是没找到。又不想写个子类,于是使用源码中的toString获取

public String toString() {
    return "native@0x" + Long.toHexString(peer);
}

分别打印

bufOut.getValue().toString();

bufOut.getPoint().toString();

发现getValue()获取的Pointer的peer值和,C++中申请的一致

最后创建

Pointer pointer = Pointer.createConstant(getPeer(bufOut.getValue()));

传入jna方法做为参数,在C++中释放内存。

对JNA不是很熟,还是很多年前用过,所以了解的不多,可能有更好的方法找到的话会贴出来做个记录。

2021-05-24

补充:

以上方式释放内存没有成功,原因不知道。但无意中找到了,获取peer的方式

long peer = Pointer.nativeValue(bufOut.getPointer());

2021-05-25

继续:

尝试使用Native.free在java端释放内存,发现和在C++中释放是一个效果,Native.free后C++会报错 free(): double free detected 说明内存已被释放,但查看系统内存,依然没有变化。。。直到java进程结束才释放掉。继续查找方法

Native.free(peer);
//int releaseResult = releaseServerRouteResult(bufOut.getValue()); 

2022-09-29

后续使用jdk的监控工具,查看内存非此处占用。可见Native.free(peer)可以成功释放掉 so中申请的内存

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值