java通过jni调用c++逻辑

时间:2022-08-10 20:20:28

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