使用Linux编译JNI程序的完整教程(linuxjni编译)
## 一、简介
Java Native Interface(JNI,Java本地接口)是一个用于Java代码与各种底层本地代码(如C或C++)交互的技术,它使得Java程序可以调用外部本地代码,也可以被本地代码调用。使用JNI使得Java程序可以调用底层本地代码,从而获得最大的执行性能。
本文主要介绍如何在Linux系统下使用Linux自带的编译器来编译JNI程序。
## 二、准备工作
### 2.1 安装JDK
要使用JNI,必须先安装JDK(Java Development Kit)环境,可以使用下面的命令安装openJDK:
sudo apt-get install openjdk-8-jdk
安装完成后,可以使用以下命令查看JAVA_HOME环境变量是否设置正确:
echo $JAVA_HOME
如果没有设置,可以通过在`/etc/environment` 文件中添加如下内容来设置:
JAVA_HOME="/usr/lib/jvm/java-8-openjdk-amd64"
### 2.2 安装gcc编辑器
`gcc`是Linux下常用的编译器;可以使用以下命令安装:
sudo apt-get install gcc
### 2.3 安装make工具
`make`是Linux下常用的自动,用于自动生成可执行文件和库的工具;可以使用以下命令安装:
sudo apt-get install make
## 三、编译JNI程序
### 3.1 编写Java程序
首先,编写一个Java文件,如:SimpleUseJni.java
“`java
public class SimpleUseJni {
public native String sayHello(String name);
public static void main(String[] args) {
System.loadLibrary(“SimpleUseJni”);
SimpleUseJni simple = new SimpleUseJni();
System.out.println(simple.sayHello(“Ikkst”));
}
}
上面的Java程序首先声明了一个`native`方法:`String sayHello(String name)`; Java代码的逻辑就是,加载“SimpleUseJni”的本地库,然后调用`sayHello`方法,参数为“Ikkst”;
### 3.2 生成头文件
接下来,要使用JDK下的一个命令,自动生成头文件,其命令如下:
```bashjavah -jni SimpleUseJni
之后,会自动生成SimpleUseJni.h文件:
“`c
/* DO NOT EDIT THIS FILE – it is machine generated */
#include
/* Header for class SimpleUseJni */
#ifndef _Included_SimpleUseJni
#define _Included_SimpleUseJni
#ifdef __cplusplus
extern “C” {
#endif
/*
* Class: SimpleUseJni
* Method: sayHello
* Signature: (Ljava/lang/String;)Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_SimpleUseJni_sayHello
(JNIEnv *, jobject, jstring);
#ifdef __cplusplus
}
#endif
#endif
这个文件就是要被C/C++程序包含的头文件。
### 3.3 编写对应的C/C++代码
然后,新建一个C/C++文件,如SimpleUseJni.c,然后根据header文件进行编写:
```C#include
#include "SimpleUseJni.h"#include
#include
// 声明一个字符串变量static const char *greeting = "Hello";
// 实现sayHello方法JNIEXPORT jstring JNICALL Java_SimpleUseJni_sayHello(JNIEnv *env, jobject jobj, jstring jstr) {
char buf[128]; strcpy(buf, greeting);
const char *str = (*env)->GetStringUTFChars(env, jstr, NULL); strcat(buf, " ");
strcat(buf, str); return (*env)->NewStringUTF(env, buf);
}
为了能够使用到本地库,还需要编写一个SimpleUseJni.cpp文件:
“`C
#include
/**
* 下面是供给JVM通过签名获取目标方法在本地库中的地址
*/
JNIEXPORT jint JNI_OnLoad(JavaVM *vm, void *reserved){
JNIEnv *env;
if ((*vm)->GetEnv(vm, (void **)&env, JNI_VERSION_1_8) != JNI_OK) {
return -1;
}
// 导入 sayHello方法
JNINativeMethod method_sayHello;
method_sayHello.name = “sayHello”;
method_sayHello.signature = “(Ljava/lang/String;)Ljava/lang/String;”;
method_sayHello.fnPtr = (void *)Java_SimpleUseJni_sayHello;
// 注册方法
jclass cls = (*env)->FindClass(env, “SimpleUseJni”);
(*env)->RegisterNatives(env, cls, &method_sayHello, 1);
return JNI_VERSION_1