概述
- 目的: java類調用C語言
- 準備: jdk環境配置, gcc
- 環境:
操作系統: CentOS Linux release 7.6.1810 (Core)
GLIBC版本: 2.17
JDK版本: 1.8
編寫Java類, 定義調用接口
- vim FirstJNI.java :
package com;
public class FirstJNI {
static{
try{
/*加載C語言動態庫: 目錄名可以自定義*/
System.load("/root/jnilibs/libFirstJNI.so");
}
catch(UnsatisfiedLinkError e){
System.out.println("Error Message:" + e.getMessage());
}
}
/*自定義調用方法echoString(): 將一個string參數打印到終端*/
public native void echoString(String str);
/*main方法測試:*/
public static void main(String[] args) {
String str = "Hello World!";
new FirstJNI().echoString(str);
}
}
- 編譯生成class : javac FirstJNI.java
當前目錄下會生成 FirstJNI.class,
由於java文件中定義了一個包名,
所以需在當前目錄下新建一個以包名命名的目錄, 並將class移至該目錄
移動好以後目錄結構如下:
調用接口的C語言實現
- 生成接口頭文件: javah com.FirstJNI
當前目錄下會生成: com_FirstJNI.h - 編輯C文件: vim FirstJNI.c
#include "com_FirstJNI.h"
/*
*接口聲明來自: com_FirstJNI.h, 必須與頭文件保持一致
*且需要加上形參名
*/
JNIEXPORT void JNICALL Java_com_FirstJNI_echoString
(JNIEnv * env, jobject obj, jstring str)
{
/*字符串類型轉換*/
const char* p_str = (*env)->GetStringUTFChars(env, str, JNI_FALSE);
/*自定義C語言代碼*/
printf("Recv String:%s\n", p_str);
/*釋放資源*/
(*env)->ReleaseStringUTFChars(env, str, p_str);
return;
}
編譯生成so
- vim makefile:
#定義JAVA_HOME變量, 以實際路徑爲準
JAVA_HOME=/usr/java/jdk1.8.0_201-amd64
all: FirstJNI.c
gcc -I$(JAVA_HOME)/include/linux/ -I$(JAVA_HOME)/include/ \
-fPIC -shared FirstJNI.c -o libFirstJNI.so
- 保存makefile運行命令: make
測試
-
將生成的 libFirstJNI.so 移至JAVA類中加載so的路徑下:
cp libFirstJNI.so /root/jnilibs/ -
在編譯目錄下運行: java com.FirstJNI
結果如下圖: