使用Java通过JNI方式调用C++动态库文件
一、写一个调用JNI动态库的JNIDemo.java文件(以下代码中调用的动态库为libvinJava.so)
public class JNIDemo {
static{
System.loadLibrary("vinJava");
}
//定义一个方法,该方法在C中实现
public native int init(String yolo_config, String yolo_weights, String regression_model, String recognition_model,String lience_path);
public native String predict(String imgPath,String lience_path);
public static void main(String[] args){
JNIDemo jn = new JNIDemo();
String cfg = "./yolov3-tiny_jiao_test.cfg",
weights = "./yolov3-tiny_jiao_29024.weights",
regress = "./vinJava/VIN_bn.pb",
recog = "./denseNetk16bn-vin-v5e15.pb",
imgFile = "./LFPH3ACC191A64774.jpg",
lience="./lib_x64";
int a= jn.init(cfg,weights,regress,recog,lience);
if(a==0)
{
System.out.println("init succeed!");
String result = jn.predict(imgFile,lience);
System.out.println("predict succeed!result is:"+result);
}
else
{
System.out.println("init faild!");
System.out.println("init return :"+a);
}
}
}
二、执行$javac JNIDemo.java,编译.java文件,生成JNIDemo.class文件
三、执行$javah -jni JNIDemo,生成C++所需的头文件JNIDemo.h
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class JNIDemo */
#ifndef _Included_JNIDemo
#define _Included_JNIDemo
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: JNIDemo
* Method: init
* Signature: (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)I
*/
JNIEXPORT jint JNICALL Java_JNIDemo_init
(JNIEnv *, jobject, jstring, jstring, jstring, jstring, jstring);
/*
* Class: JNIDemo
* Method: predict
* Signature: (Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_JNIDemo_predict
(JNIEnv *, jobject, jstring, jstring);
#ifdef __cplusplus
}
#endif
#endif
四、新建JNIDemo.h对应的源文件JNIDemo.cpp
JNIEXPORT jint JNICALL Java_JNIDemo_init
(JNIEnv * env, jobject obj, jstring cfg, jstring weights, jstring regress, jstring recog, jstring lience)
{函数实现的.cpp代码}
JNIEXPORT jstring JNICALL Java_JNIDemo_predict
(JNIEnv * env, jobject, jstring img_path, jstring lience)
{函数实现的.cpp代码}
五、新建CMakeLists.txt文件生成.so文件
利用CMakeLists.txt生成.so文件,具体需要哪些.h文件和库文件见CMakeLists.txt使用说明(本人的整理的相关文章:https://mp.csdn.net/postedit/99713860)
六、重新编译文章开始的JNIDemo.java文件,即执行$javac JNIDemo.java(这一步可不执行,因为一开始已经执行了)
七、JAVA调用生成的.so文件
执行$java -Djava.library.path='/home/wangjiao/jiao_code/jni/vinJava' JNIDemo
-Djava.library.path是指生成的.so所在的路径,如果没有这个参数可能会报找不到这个so的错误
至此,完成JNI实现Java调用C++程序!
八、以上是没有包的jni调用C++程序,如果需要加包则应该如下(可使用idea进行编译):
例如:
在JNIDemo.java的开始添加一行语句如下:
package com.gongsi.project (代表JNIDemo.java文件在路径com/gongsi/project下面)
在生成.h文件时应该执行$javah -jni com.gongsi.project.JNIDemo
参考文章:https://blog.csdn.net/Wang_Xin_SH/article/details/77816183