本博客通过一个简单的例子通过用java调c++处理,逻辑不带返回,直接打印hello word级别的,下面来看下,首先写一个java简答的测试类:
package com.xx.odps.ainlp;
public class HelloWorld {
//导入lib文件
static{
System.load("libjnite.dylib");
}
// 调用 c++ 代码的函数
public native void myprint();
public static void main(String[] args) {
new HelloWorld().myprint();
}
}
通过javah生成c++头文件:
注意这个类的package,生成头文件,一定要去这个package开始目录生成,我用下面的命令生成,否则会报错,用下面的命令直接生成:
javah com.xx.odps.ainlp.HelloWorld
在这里会生成一个头文件,com_xx_odps_ainlp_HelloWorld.h 这个文件,命名和类所在package是一样的,
下面建立一个c++项目打包成dylib文件,
com_xx_odps_ainlp_HelloWorld.h:
/* DO NOT EDIT THIS FILE - it is machine generated */
#include "jni.h"
/* Header for class com_xx_odps_ainlp_HelloWorld */
#ifndef _Included_com_xx_odps_ainlp_HelloWorld
#define _Included_com_xx_odps_ainlp_HelloWorld
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: com_xx_odps_ainlp_HelloWorld
* Method: myprint
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_com_xx_odps_ainlp_HelloWorld_myprint(JNIEnv *, jobject);
#ifdef __cplusplus
}
#endif
#endif
com_xx_odps_ainlp_HelloWorld.cpp文件:
#include "jni.h"
#include "com_xx_odps_ainlp_HelloWorld.h"
#include <iostream>
using namespace std;
JNIEXPORT void JNICALL Java_com_xx_odps_ainlp_HelloWorld_myprint(JNIEnv *, jobject) {
cout<<"hello world"<<endl;
}
还要依赖java自带的 jni.h和jni_md.h 文件,这两个文件在java的jre include目录下
CMakeLists.txt文件内容:
cmake_minimum_required(VERSION 3.10) project(jnitest) set(CMAKE_CXX_STANDARD 11) add_library(jnite SHARED com_xx_odps_ainlp_HelloWorld.h com_xx_odps_ainlp_HelloWorld.cpp jni_md.h jni.h) target_link_libraries(jnite)
编译成dylib文件:
mkdir build
cmake ..
make
会生成一个dylib文件,在java中引用既可以。
然后在java中直接静态引入,既可以,前几年比较火热的xgboost包也是通过jni给java调用预测,其本质并没有用java实现
任何逻辑,java只是一层壳,包括现在如火如荼的tensorflow也一个样。。