Linux下eclipse中通過jni調(diào)用.so實(shí)例

系統(tǒng)環(huán)境:64位Ubuntu14.04斥赋、eclipse 5.3版本授账,jdk1.8版本,vim編譯器

1亭枷、本實(shí)例是java代碼通過jni調(diào)用c/c++語言生成的.so庫,本庫提供兩個(gè)方法搀崭,當(dāng)調(diào)用讀目錄方法叨粘,并輸入一個(gè)目錄的路徑時(shí),會(huì)打印出輸入目錄下的所有文件瘤睹,當(dāng)調(diào)用升敲,讀文件方法,并輸入一個(gè)目錄文件的路徑會(huì)讀取本文件的前五個(gè)字節(jié)轰传,并創(chuàng)建一個(gè)和輸入文件名相同后綴添加一個(gè).new的文件驴党,然后將讀取的五個(gè)字節(jié)寫入到本文件中。

2获茬、在eclipse中創(chuàng)建一個(gè)類港庄,流程如下File->New->Java Project->在Projectname框中寫入項(xiàng)目名稱->點(diǎn)擊finish。右擊右側(cè)欄的項(xiàng)目中的src選擇new->Package->在name中輸入demo(這是java中的包名)->Finish恕曲,然后右擊src下的demo->new->class->在name框中輸入MainClass(這個(gè)是類名)鹏氧。

3、在類中寫如下代碼

Java代碼

package demo;

importjava.io.BufferedReader;

importjava.io.IOException;

importjava.io.InputStreamReader;

public classMainClass {

static

{

//在linux中可使用這個(gè)函數(shù)然后直接寫so的絕對路徑加載so文件

System.load("/home/native/read_dir_file/libTestReadFile.so");

}

//在MainClass類中定義了一個(gè)String結(jié)構(gòu)體

public String message = null;

public native void callCppFunction();

public native void read_dir();

public native void read_file();

public static void main(String [] args) throwsIOException

{

BufferedReader reader = newBufferedReader(newInputStreamReader(System.in));

String str = reader.readLine();

MainClass obj = new MainClass();

obj.message = str;

//obj.callCppFunction();

//obj.read_dir();//讀取目錄的方法

obj. read_file();//讀取文件的方法

System.out.println("Javaoutput:" + obj.message);

}

}

4佩谣、進(jìn)入java所在的目錄src/demo/目錄下執(zhí)行javac MainClass.java(這個(gè)是剛剛寫的java文件)把还,生成一個(gè)MainClass.class文件 進(jìn)入bin的上一層目錄然后進(jìn)入bin目錄下,執(zhí)行javah demo.MaicClass這時(shí)候在當(dāng)前目錄下生成一個(gè)MainClass.h文件茸俭,把這文件拷貝到寫c的目錄下吊履。

頭文件內(nèi)容如下

Java代碼,c的頭文件相同

MainClass.h

/* DO NOT EDIT THIS FILE - it is machine generated */

#include

/* Header for classdemo_MainClass */

#ifndef_Included_demo_MainClass

#define_Included_demo_MainClass

#ifdef __cplusplus

extern "C"{

#endif

/*

* Class:demo_MainClass

* Method:callCppFunction

* Signature: ()V

*/

JNIEXPORT voidJNICALL Java_demo_MainClass_callCppFunction

(JNIEnv *, jobject);

/*

* Class:demo_MainClass

* Method:read_dir

* Signature: ()V

*/

JNIEXPORT void JNICALLJava_demo_MainClass_read_1dir

(JNIEnv *, jobject);//注意這里它會(huì)自動(dòng)添加一個(gè)數(shù)字1

/*

* Class:demo_MainClass

* Method:read_file

* Signature: ()V

*/

JNIEXPORT void JNICALL Java_demo_MainClass_read_1file

(JNIEnv *, jobject);

#ifdef __cplusplus

}

#endif

#endif

5调鬓、在和.h同一目錄下艇炎,創(chuàng)建一個(gè)MainClass.c文件文件內(nèi)容如下

MainClass.c內(nèi)容如下:

cpp代碼

#include"demo_MainClass.h"

#include <stdio.h>

#include <stdlib.h>

#include <dirent.h>

#include <unistd.h>

#include <sys/types/h>

#include <string.h>

//讀取目錄函數(shù)

int cont = 0;

intdir_file_num(char * dirname)

{

printf("%sdir:\n", dirname);

DIR *dirp = opendir(dirname);//打開目錄

if(dirp == NULL)

{

perror("open dir err");

return -1;

}

struct dirent * dentp = NULL;

//讀取目錄中所用文件

while((dentp = readdir(dirp)))

{

if(dentp->d_type == DT_REG)

{

printf("%s\n",dentp->d_name);

cont++;

}

if(dentp->d_type == DT_DIR)

{

if((strcmp(".",dentp->d_name)) ==0 || (strcmp("..", dentp->d_name)) == 0)

{

continue;

}

char new_dir_name[256] = {0};

sprintf(new_dir_name,"%s/%s",dirname, dentp->d_name);//directoryfull path

dir_file_num(new_dir_name);

}

}

return cont;

}

//讀取文件前5個(gè)字節(jié)

intread_file_info(char *filename)

{

if(NULL == filename)

{

return -1;

}

printf("%s", filename);

FILE *fd;

size_t i = 0;

char buf[24] = {0};

charnew_file_name[256]={0};

sprintf(new_file_name, "%s.new",filename);

//讀取文件前五個(gè)字節(jié)

if(!(fd = fopen(filename, "r")))

{

return -2;

}

i = fread(buf, 1, 5, fd);

if( i < 5)

{

printf("文件讀取失敗!\n");

return -3;

}

fclose(fd);

fd = fopen(new_file_name, "w");

if(fd == NULL)

{

printf("文件打開失敗");

return -4;

}

i = fwrite(buf, 1, 5, fd);

if(i == 0)

{

printf("文件寫入失敗\n");

return -5;

}

fclose(fd);

return 0;

}

JNIEXPORT void

JNICALLJava_demo_MainClass_callCppFunction(JNIEnv *env, jobject obj)

{

jclass clazz;

jfieldID fid;

jstring j_str;

jstring j_newStr;

const char *c_str = NULL;

//獲取MainClass類的Class引用

clazz = (*env)->GetObjectClass(env, obj);

if(NULL == clazz)

{

return;

}

//獲取MainClass類實(shí)例變量message的屬性ID

fid = (*env)->GetFieldID(env, clazz,"message", "Ljava/lang/String;");

if(fid < 0)

{

return;

}

//獲取實(shí)例message的值

j_str = (jstring)(*env)->GetObjectField(env,obj, fid);

if(NULL == j_str)

{

return;

}

//將Unicode編碼的java字符串轉(zhuǎn)換為c風(fēng)格的字符串

c_str = (*env)->GetStringUTFChars(env,j_str, NULL);

if(NULL == c_str)

{

return;

}

int i = 0;

//調(diào)用顯示目錄下文件的函數(shù)

i = dir_file_num((char *)c_str);

if(i < 0)

{

printf("dir_file_num err!\n");

return;

}

}

//打印目錄下所用文件

JNIEXPORT void

JNICALLJava_demo_MainClass_read_1dir(JNIEnv *env, jobject obj)

{

jclass clazz;

jfieldID fid;

jstring j_str;

jstring j_newStr;

const char *c_str = NULL;

//獲取MainClass類的Class引用

clazz = (*env)->GetObjectClass(env, obj);

if(NULL == clazz)

{

return;

}

//獲取MainClass類實(shí)例變量message的屬性ID

fid =(*env)->GetFieldID(env, clazz, "message","Ljava/lang/String;");

if(fid < 0)

{

return;

}

//獲取實(shí)例message的值

j_str =(jstring)(*env)->GetObjectField(env, obj, fid);

if(NULL == j_str)

{

return;

}

//將Unicode編碼的java字符串轉(zhuǎn)換為c風(fēng)格的字符串

c_str = (*env)->GetStringUTFChars(env,j_str, NULL);

if(NULL == c_str)

{

return;

}

int i = 0;

//調(diào)用顯示目錄下文件的函數(shù)

i = dir_file_num((char*)c_str);

if(i < 0)

{

printf("dir_file_numerr!\n");

return;

}

}

//讀取文件前5個(gè)字節(jié)

JNIEXPORT void

JNICALLJava_demo_MainClass_read_1file(JNIEnv *env, jobject obj)

{

//定義變量

jclass clazz;

jfieldID fid;

jstring j_str;

jstring j_newStr;

const char *c_str = NULL;

//獲取MainClass類的Class引用

clazz = (*env)->GetObjectClass(env, obj);

if(NULL == clazz)

{

return;

}

//獲取MainClass類實(shí)例變量message的屬性ID

fid = (*env)->GetFieldID(env, clazz,"message", "Ljava/lang/String;");

if(fid < 0)

{

return;

}

//獲取實(shí)例message的值

j_str =(jstring)(*env)->GetObjectField(env, obj, fid);

if(NULL == j_str)

{

return;

}

//將Unicode編碼的java字符串轉(zhuǎn)換為c風(fēng)格的字符串

c_str = (*env)->GetStringUTFChars(env,j_str, NULL);

if(NULL == c_str)

{

return;

}

int i = 0;

//調(diào)用讀取文件函數(shù)

i = dir_file_num((char *)c_str);

if(i < 0)

{

printf("dir_file_num err!\n");

return;

}

}

6、代碼寫完之后開始制作動(dòng)態(tài)庫袖迎,首先執(zhí)行

gcc -fPIC -D_REENTRANT-I/home/jdk1.8.0_77/include -I/home/jdk1.8.0_77/include/linux -cdemo_MainClass.c

生成一個(gè).o文件冕臭,這里的/home/jdk1.8.0_77/include是我主機(jī)中jni.h所在路徑,/home/jdk1.8.0_77/include/linux是jni.h所在路徑燕锥,然后執(zhí)行

gcc -shareddemo_MainClass.o -o libTestReadFile.so

生成一個(gè)libTestReadFile.so文件辜贵,這里的demo_MainClass.o就是上一步生成的.o文件。

7归形、這里就已經(jīng)完成了在Ubuntu下中的eclipse調(diào)用.so文件了托慨,這時(shí)候就可以在eclipse中執(zhí)行了,然后輸入一個(gè)目錄路徑就可以了暇榴。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末厚棵,一起剝皮案震驚了整個(gè)濱河市蕉世,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌婆硬,老刑警劉巖狠轻,帶你破解...
    沈念sama閱讀 211,265評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異彬犯,居然都是意外死亡向楼,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,078評(píng)論 2 385
  • 文/潘曉璐 我一進(jìn)店門谐区,熙熙樓的掌柜王于貴愁眉苦臉地迎上來湖蜕,“玉大人,你說我怎么就攤上這事宋列≌咽悖” “怎么了?”我有些...
    開封第一講書人閱讀 156,852評(píng)論 0 347
  • 文/不壞的土叔 我叫張陵炼杖,是天一觀的道長灭返。 經(jīng)常有香客問我,道長坤邪,這世上最難降的妖魔是什么婆殿? 我笑而不...
    開封第一講書人閱讀 56,408評(píng)論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮罩扇,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘怕磨。我一直安慰自己喂饥,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,445評(píng)論 5 384
  • 文/花漫 我一把揭開白布肠鲫。 她就那樣靜靜地躺著员帮,像睡著了一般。 火紅的嫁衣襯著肌膚如雪导饲。 梳的紋絲不亂的頭發(fā)上捞高,一...
    開封第一講書人閱讀 49,772評(píng)論 1 290
  • 那天,我揣著相機(jī)與錄音渣锦,去河邊找鬼硝岗。 笑死,一個(gè)胖子當(dāng)著我的面吹牛袋毙,可吹牛的內(nèi)容都是我干的型檀。 我是一名探鬼主播,決...
    沈念sama閱讀 38,921評(píng)論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼听盖,長吁一口氣:“原來是場噩夢啊……” “哼胀溺!你這毒婦竟也來了裂七?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,688評(píng)論 0 266
  • 序言:老撾萬榮一對情侶失蹤仓坞,失蹤者是張志新(化名)和其女友劉穎背零,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體无埃,經(jīng)...
    沈念sama閱讀 44,130評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡徙瓶,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,467評(píng)論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了录语。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片倍啥。...
    茶點(diǎn)故事閱讀 38,617評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖澎埠,靈堂內(nèi)的尸體忽然破棺而出虽缕,到底是詐尸還是另有隱情,我是刑警寧澤蒲稳,帶...
    沈念sama閱讀 34,276評(píng)論 4 329
  • 正文 年R本政府宣布氮趋,位于F島的核電站,受9級(jí)特大地震影響江耀,放射性物質(zhì)發(fā)生泄漏剩胁。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,882評(píng)論 3 312
  • 文/蒙蒙 一祥国、第九天 我趴在偏房一處隱蔽的房頂上張望昵观。 院中可真熱鬧,春花似錦舌稀、人聲如沸啊犬。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,740評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽觉至。三九已至,卻和暖如春睡腿,著一層夾襖步出監(jiān)牢的瞬間语御,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,967評(píng)論 1 265
  • 我被黑心中介騙來泰國打工席怪, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留应闯,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,315評(píng)論 2 360
  • 正文 我出身青樓何恶,卻偏偏與公主長得像孽锥,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,486評(píng)論 2 348

推薦閱讀更多精彩內(nèi)容