Jni學習總結
一,在java中的jni的編寫方法
1.第一步,在JAVA中要做的工作
(1).創建一個JAVA的工程
(2).在工程裏面創建一個Test的類
(3).在Test類裏面加載動態庫
(4).生成native方法
(5).創建主函數,調用jni實現的方法
代碼如下:
package test;
publicclass Test {
/*用於加載動態庫文件,動態鏈接庫名字爲libtest.so*/
static{
System.loadLibrary("test");
}
/*聲明一個native的方法*/
publicnativevoid test();
publicstaticvoid main(String[] args){
/*調用Test類的test()方法*/
new Test().test();
System.out.println("Hello , it's my javav JNI .\n");
}
}
2.編譯這個java文件,生成class文件
(1)進入到工程中的java文件的目錄下
(2)編譯java文件生成class文件
代碼如下:
cd /root/Desktop/android_jni/java_jnitest/src/test
javac Test.java
3.使用javah這個工具生成test_Test.h的頭文件
(1)進入到工程文件的源碼目錄
(2)執行javah工具生成.h文件
代碼如下:
cd /root/ Desktop/android_jni/java_jnitest/src
javah -jni test.Test
test_Test.h文件的內容爲如下
/* DO NOT EDIT THIS FILE - it is machine generated */
#include<jni.h>
/* Header for class test_Test */
#ifndef _Included_test_Test
#define _Included_test_Test
#ifdef __cplusplus
extern"C" {
#endif
/*
* Class: test_Test
* Method: test
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_test_Test_test
(JNIEnv *, jobject);
#ifdef __cplusplus
}
#endif
#endif
當然這個.h文件我們也可以手寫,但是必須的符合一些規則,首先解釋一下這個.h文件吧,需要包含jni.h頭文件,然後
#ifndef
#define
#endif
這個是防止重複的定義這段代碼
還有個東東extern “C”{
}
由於在JAVA和C++中存在重載這個東西,但是C語言不包含重載這個概念,就產生了這個東東,它主要是在函數的命名上來區分。所以這裏如果是C語言的化,我們會開啓這個東東,來給我們的jni函數按這樣的規則命名。如果是C++則不用它會自動的轉換爲這種規則命名。
4.編寫我們的C代碼
(1)包含需要的頭文件
(2)實現.h中的函數
#include<stdio.h>
#include <jni.h>
#include"../test_Test.h"
JNIEXPORT
void JNICALL Java_test_Test_test(JNIEnv *env, jobject jb)
{
printf("This is my java JNI test .\n");
}
5.生成動態鏈接庫
(1)進入包內
(2)使用gcc生成動態鏈接庫
代碼如下:
cd /root/Desktop/android_jni/java_jnitest/src/test
gcc -I /usr/lib/jvm/java-6-openjdk/include/ -fPIC -shared -o libtest.so test.c
6.設置環境變量並運行測試
(1)設置環境變量,在加載.so文件時會自動到該環境變量下查找(僅在當前shell有效)
(2)記得回到源碼目錄(src目錄下)
(3)執行測試
代碼如下:
export LD_LIBRARY_PATH=”/root/Desktop/android_jni/java_jnitest/src/test“
cd /root/Desktop/android_jni/java_jnitest/src
java test.Test