18.jpg
前言
其实这篇文章重点在如何用Java的JNI调用C++的dll,记录一下,避免以后自己忘了.....
原文发表在语雀文档上,排版更美观
简介
JNI—摘自百度百科
JNI是Java Native Interface的缩写,它提供了若干的API实现了Java和其他语言的通信(主要是C&C++)。从Java1.1开始,JNI标准成为java平台的一部分,它允许Java代码和其他语言写的代码进行交互。JNI一开始是为了本地已编译语言,尤其是C和C++而设计的,但是它并不妨碍你使用其他编程语言,只要调用约定受支持就可以了。使用java与本地已编译的代码交互,通常会丧失平台可移植性。但是,有些情况下这样做是可以接受的,甚至是必须的。例如,使用一些旧的库,与硬件、操作系统进行交互,或者为了提高程序的性能。JNI标准至少要保证本地代码能工作在任何Java 虚拟机环境。
由于近期在玩yolo、darknet,C++项目下的图像识别(目标检测),想尝试下将生成的dll提供给Java服务端调用,于是就有了本篇文章~记个流水账怕以后自己忘了....
流程
整体来说,要直接将dll被java调用是不可能的,因为两种语言基本数据类型、方法定义这些是不同的,所以需要用VS新建一个dll项目,生成java项目中可调用的dll。
1.新建native接口方法类
在Java项目中任意位置新建一个类,声名需要用到的native方法,凡是用native修饰的方法,都是后面调用的dll中的方法(C++实现),static块中System.load方法即可实现加载dll,在刚开始这部分可以忽略不写,等VS生成dll后再过来添加。
DarknetJavaSDK.java
package com.xxx.ai.image.detection.service.sdk;
import java.io.File;
public class DarknetJavaSDK {
public native String get_version();
public native boolean set_logfile_path(String logPath);
public native boolean load_model(String cfgPath, String modelPath);
public native int detect_image(String imagePath, String outDirPath);
2.生成.h头文件
生成头文件时,因为DarknetJavaSDK.java文件从属于包:
package com.xxx.ai.image.detection.service.sdk;所以,需要cd到.../src/main/java目录下(即com/xxx/ai的上一级目录),运行:
javah com.xxx.ai.image.detection.service.sdk.DarknetJavaSDK
即可在当前目录下生成.h文件:com_xxx_ai_image_detection_service_sdk_DarknetJavaSDK.h
特别注意:如果当前类:DarknetJavaSDK.java 中有依赖其他你自定义的Java类,则可能报错,因为类加载的路径中找不到。解决方法:指定-classpath到.../src/main/java目录下