java linux动态库 签名_java实现linux下调用c的so动态库的方法

最近项目中用到了java调用linux系统下c的so动态库的需求,实现后我就来总结一波

实现方式:

1.java使用jni调用so库:

需要自己定义native方法,编译.h文件,编写c文件,在linux上编译为so文件,巴拉巴拉。。。

总之比较繁琐,而且写java的去写c,你懂得。。。

2.对jni做了封装的JNA方法:

将c中的类型与Java中的类型做了映射,只需要写一个类,类中的接口extends Library来实例化代码,加载c的.so文件就可以了,怎么样,听起来是不是比jni的调用方式简单很多呢?

前期准备,maven依赖

1.要使用JNA当然需要依赖于其jar包了,那么相应的依赖的引入就必不可少了,依赖如下:

net.java.dev.jna

jna

5.2.0

net.java.dev.jna

jna-platform

5.2.0

示例代码

1.so中代码或者是cpp文件中要调用方法的定义:

int ppdetect(char *modelPath,cv::Mat &input_img, int

* column, int gpuid, int *boxX, int *boxY, int *boxWidth, int *boxHeight, int

*numBox);

2.java中封装代码的实例(注意方法名要与c中定义一致,否则会找不到方法):

import java.awt.AlphaComposite;

import java.awt.Graphics2D;

import java.awt.image.BufferedImage;

import java.awt.image.DataBufferByte;

import java.io.ByteArrayInputStream;

import java.io.File;

import java.io.FileInputStream;

import java.io.IOException;

import java.io.InputStream;

import javax.imageio.ImageIO;

import org.opencv.core.Core;

import org.opencv.core.CvType;

import org.opencv.core.Mat;

import org.opencv.core.Rect;

import com.sun.jna.Library;

import com.sun.jna.Native;

import com.sun.jna.Pointer;

import com.sun.jna.ptr.IntByReference;

import sun.misc.BASE64Decoder;

public class CallSoUtils {

/**

* 继承Library,用于加载库文件

* @author I

*

*/

public interface PPLibrary extends Library {

//linux下代码编译出来的文件实际上是libPPDetectSDK.so文件,但是在代码中需要去掉lib和.so

PPLibrary INSTANTCE = (PPLibrary) Native.loadLibrary("PPDetectSDK", PPLibrary.class);

// 此方法为链接库中的方法

/*

* int ppdetect(char *modelPath,cv::Mat &input_img, int

* column, int gpuid, int *boxX, int *boxY, int *boxWidth, int *boxHeight, int

* *numBox);

*/

int ppdetect(String modelPath,long matImgAddress,int column,int gpuid,int[] boxX,

int[] boxY, int[] boxWidth, int[] boxHeight,IntByReference numBox);

}

/**

* windows下调用add_core_lite.dll文件,可以写全dll文件名,可以是全路径,如果不是全路径需要将dll文件放到jdk

* 的bin目录下

* @author I

*

*/

public interface TestDllInterface extends Library {

TestDllInterface INSTANTCE = (TestDllInterface) Native.loadLibrary("add_core_lite", TestDllInterface.class);

boolean calcvalptr(int[] paramin, int numb_in,int[] pAns, IntByReference numb_out);

}

}

3.java调用封装类的方法实例(mvc中controller代码,有一些删减,关注方法里边的思路,或者自己提取到main方法中 也可以):

@RequestMapping(value = "/ppdec", method = { RequestMethod.POST })

public String paperSplit(@RequestBody final JSONObject parseObject) {

String result = "";

try {

// base64编码图片信息

String base64 = parseObject.getString("base64");

// model 路径

String modelPath = parseObject.getString("modelPath");

Mat matrix = null;

try {

//自定义的实现base64转mat方法

matrix = Base2MatTools.base642Mat(base64);

} catch (IOException e) {

}

int column = 3;

int gpuid = 2

int[] boxX = new int[3];

int[] boxY = new int[3];

int[] boxWidth = new int[3];

int[] boxHeight = new int[3];

IntByReference numBox = new IntByReference(0);

// 使用jna进行算法的调用,mat传递的是地址

int ret = PPLibrary.INSTANTCE.ppdetect(modelPath, matrix.getNativeObjAddr(),

column, gpuid, boxX, boxY, boxWidth, boxHeight, numBox);

List rectList = new ArrayList();

if (numBox != null && numBox.getValue() > 0) {

for (int i = 0; i < numBox.getValue(); i++) {

int x = boxX[i];

int y = boxY[i];

int w = boxWidth[i];

int h = boxHeight[i];

Rect rect = new Rect(x, y, w, h);

rectList.add(rect);

}

}

jsonObject.put("status", "success");

jsonObject.put("code", "200");

jsonObject.put("data", rectList);

return jsonObject.toString();

} catch (Exception e) {

}

return result;

}

一个demo完成了。

可能好多人弄不懂为什么这样写,那么我就将JNA中java和c的对应关系甩到下边供各位参考

3ffed468b1c0e439a6e62741ad2bd62b.png

048a431d140cdc01970d66844515f445.png

这其实只是一个参考,向int& 实际上很可能需要转换的是int[],而不是IntByReference

【注】使用JNA最重要的就是对应类型的转换,要是类型的转换出现错误,分分钟让你jvm崩溃,所以一定要注意哦。

另外,假如传递的是Mat类型的数据注意一定传递的是指针地址,而不是整个Mat类型的数据,要不然一样崩溃给你看啊啊啊啊啊…。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值