使用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下的一个命令,自动生成头文件,其命令如下:

```bash
javah -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


数据运维技术 » 使用Linux编译JNI程序的完整教程(linuxjni编译)