最近协助同事解决了JNI调用及回调问题,在此做个记录,备忘。
问题是这样子的:同事要开发一个java程序,用来控制摄像头的抓拍,且要通过回调字节流的方式,将抓拍的图片吐给java模块,然后再调人脸识别服务。期间遇到不少问题,最开始用JNA实现了整体功能,但是测试过程发现回调总是不稳定,照片有些时候传不回来。无耐之下,只要改用JNI再试,谁知JNI果然比JNA复杂,又是各种问题,不过还好问题都解决了,在此总结下JNI调用及回调流程。
JNI使用步骤:
1、编写Java代码,其中要注明调用DLL的native方法;
2、通过javah命令,针对java代码生成c头文件;
3、基于c头文件,编写对应的函数实现,一般通过在此实现中调用真正需要交互的dll函数;
完成这3步,基本就可以完成dll调用了。对于回调,需要在c代码中,基于jni api获取要调用的类名、方法名、参数等,特别要注意参数类型的对应关系。
实例分享:
1、编写Java类
import java.io.FileOutputStream;
import java.io.IOException;
//摄像机控制类
public class CameraCtl {
//加载dll库,注意需要将库放入项目根目录,或者设置native library路径到dll目录
static {
System.loadLibrary("HwCameraSdk");
}
//映射到C的本地方法
public native void startHwCamera();
//C的回调方法,通过参数传递字节数组,其实是图片信息
public void hwCameraCallback(byte[] byteAry) {
FileOutputStream out = null;
try {
out = new FileOutputStream("./test3.jpg");
out.write(byteAry);
out.flush();
} catch (Exception