Linux环境下使用java jni调用C、C++程序

Linux环境下使用java jni调用C、C++程序

前言

由于工作需要,必须使用FPGA硬件加速算法,但是算法又是使用C和C++实现的,而项目是web项目,是通过Java实现的,这就涉及到java调C\C++。下面是本人测试Java调C(C和C++的流程差不多,下面统称C)的流程,采用的技术是Java jni(Java本地接口)。

实现流程

  1. 首先我们需要编写一个简单的demo用来调用C程序。代码如下:
//这个包结构一定要记住后面经常会涉及路径相关的东西
package com.jni;
public class Hello{
static{
//加载指定文件夹中的动态库
//这里的路径是你自己存放最后生成的so动态库的地址
System.load("/home/test/lib/libHello.so");
}
//为C程序定义一个无参无返回值的方法
//如果是已经写好的C程序,这里就要调用C程序中对应的函数
public native void say();
//为C程序定义一个带参带返回值的方法
public native String world(String str);
//这里写个main方法是为了省事,有main方法,IDE运行一下会自动生成class文件,无需自己在编译,也方便稍后的调用
public static void main(String...args){
Hello hello = new Hello();
hello.say();
System.out.println("java : "+hello.world("hello"));
}
}
  1. 编译Hello.java - Hello.class

     javac -d . Hello.java 
    

    会得到 bin/com/jni/Hello.class

  2. 跳转到你项目所在的bin目录,记住一定是bin目录,依次输入如下命令:

[root@58 bin]# javah -classpath . -jni com.jni.Hello
[root@58 bin]# touch Hello.cpp
[root@58 bin]# vi Hello.cpp 
//编辑插入下方解释位置的C++代码
[root@58 bin]# g++ Hello.cpp -fPIC -D_REENTRANT -I/usr/local/jdk1.8.0_181/include -I/usr/local/jdk1.8.0_181/include/linux -shared -o libHello.so

解释一下
第一句的意思是编译Hello.class 生成 com_jni_Hello.h 的头文件
第二句是创建一个c++文件用来测试
第三句是编辑这个c++文件,插入如下代码

#include "com_jni_Hello.h"
#include "string.h"
JNIEXPORT void JNICALL Java_com_jni_Hello_say(JNIEnv *env, jobject object){
printf("hello world!");
}
JNIEXPORT jstring JNICALL Java_com_jni_Hello_world(JNIEnv *env, jobject obejct, jstring string){
const char *wd = " world!!";
const char *getstr = env->GetStringUTFChars(string,JNI_FALSE);
char *str;
str=strcpy(str,wd);
str=strcpy(str,getstr);
jstring out= env->NewStringUTF(str);
        return out; 
}

代码中涉及转码问题,不懂得可以看看下方两个博主写的,很详细。
转码原理
转码代码
这段c代码的开头加入了我们生成的com_jni_Hello.h头文件,代码的目的就是实现头文件中所存在的两个方法,就是java代码里定义的两个方法。看到C里定义的方法名就会明白,这个方法名和类型都是要和java里对应的,这里的方法名还包含了java类所在的路径信息。
第四句是生成.so动态库文件,生成库文件不仅仅需要这段C程序,还需要拿到jdk中的两个文件,分别是在jdk安装目录下include下的jni.h和include文件夹下Linux文件夹下的jni_md.h一起生成so文件。-I 所加的文件都将一起打包,so文件名应该以lib开头。
然后把生成的so文件放在一开始java程序设定的目录/home/test/lib中,运行程序即可。

你可能感兴趣的:(Linux环境下使用java jni调用C、C++程序)