本博客通过一个简单的例子通过用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也一个样。。