最近工作中在java工程中通過(guò)jni調(diào)用c程序編譯的庫(kù)進(jìn)行加解密联贩,總結(jié)一下jni的用法
環(huán)境:macos 10.12.6,jdk7
- 編寫(xiě)一個(gè)包含native方法的java文件
System.load()和System.loadLibrary()的區(qū)別可以看這里,簡(jiǎn)單來(lái)說(shuō)load是從指定位置加載一個(gè)單獨(dú)的庫(kù)文件(參數(shù)是庫(kù)文件的全路徑),loadLibrary是從java.library.path加載庫(kù)文件(參數(shù)是文件名涂籽,不包括擴(kuò)展名,macos會(huì)自動(dòng)找lib+文件名+.dylib)砸抛。如果庫(kù)文件依賴(lài)別的庫(kù)文件评雌,load需要自己再引入树枫,loadLibrary可以自動(dòng)在java.library.path找到并引入【岸可以通過(guò)
System.getProperty("java.library.path")
查看java.library.path路徑是什么砂轻,因?yàn)閘oadLibrary對(duì)不同平臺(tái)的規(guī)則不一樣,所以還是使用load好一點(diǎn)斤吐,對(duì)名字和文件位置沒(méi)有要求
package com.lfz;
import java.io.File;
public class Main {
static {
System.load(Main.class.getResource(File.separator).getPath()+"libhelloJNI.dylib");
}
public static void main(String[] args) {
System.out.println(new Main().max(7, 5));
}
public native int max(int a, int b);
}
- 編譯java文件得到class文件
因?yàn)槲沂褂玫膇de自動(dòng)就會(huì)在classpath下編譯java源文件搔涝,所以不需要使用javac命令手動(dòng)編譯
- 調(diào)用javah命令生成c程序頭文件
進(jìn)入classpath下執(zhí)行javah命令,注意是后面是完整類(lèi)名(包名+類(lèi)名)和措,得到
com_lfz_Main.h
文件
cd $CLASS_PATH
javah com.lfz.Main
- 在和
com_lfz_Main.h
同一目錄下庄呈,編輯c文件(名字可以隨便取)
c程序頭文件引入<>和""區(qū)別,可以看這里派阱,簡(jiǎn)單來(lái)說(shuō)<>是從系統(tǒng)默認(rèn)的位置找頭文件诬留,""是先從當(dāng)前位置找再去系統(tǒng)默認(rèn)的地方找
#include <jni.h> //引入jni的頭文件
#include "com_lfz_Main.h" //引入剛才產(chǎn)生的h文件
#include <stdio.h>
// 返回值類(lèi)型jint對(duì)應(yīng)java的int類(lèi)型,方法名規(guī)則:Java_包名_類(lèi)名_方法名
// 方法參數(shù)前兩個(gè)是固定的贫母,之后對(duì)應(yīng)java native方法中的參數(shù)類(lèi)型
JNIEXPORT jint JNICALL Java_com_lfz_Main_max(JNIEnv *env,jobject obj,jint a,jint b){
return a>b?a:b;
}
- 使用gcc編譯c源文件得到庫(kù)文件
-dynamiclib代表生成動(dòng)態(tài)庫(kù)文兑,-I /System/Library/Frameworks/JavaVM.framework/Headers代表添加額外的頭文件路徑(macos的jni.h在這里,別的os需要修改這里)颁独,-o libhelloJNI.dylib代表最后編譯出的庫(kù)文件名
gcc -dynamiclib -I /System/Library/Frameworks/JavaVM.framework/Headers helloJNI.c -o libhelloJNI.dylib
對(duì)于引用類(lèi)型則有:jobject, jstring, jthrowable, jclass, jarray, 以及繼承于jarray彩届,對(duì)應(yīng)于其原生類(lèi)型的8種jarray和jobjectarray。