linux下JNI的demo

來源:互聯網
上載者:User
java訪問C/C++有6步
1.寫java檔案
2.編譯java產生class
3.產生C/C++標頭檔。
4.寫C/C++檔案
5.編譯產生dll(Window下)或so檔案
6.運行java程式
下面介紹ubutun下一個JNI例子

1.編寫Sample1.java檔案:

   public class Sample1<br /> {<br />public native int intMethod(int n);<br />public native boolean booleanMethod(boolean bool);<br />public native String stringMethod(String text);<br />public native int intArrayMethod(int[] intArray);</p><p>public static void main(String[] args)<br />{<br />System.loadLibrary("Sample1");<br />Sample1 sample = new Sample1();<br />int square = sample.intMethod(5);<br />boolean bool = sample.booleanMethod(true);<br />String text = sample.stringMethod("JAVA");<br />int sum = sample.intArrayMethod(<br />new int[]{1,1,2,3,5,8,13} );</p><p>System.out.println("intMethod: " + square);<br />System.out.println("booleanMethod: " + bool);<br />System.out.println("stringMethod: " + text);<br />System.out.println("intArrayMethod: " + sum);<br /> }<br /> }

 兩個地方要注意,
 一。上面的方法都用到了native關鍵字。
 二。System.loadLibrary("Sample1");這句中"Sample1"是我們在第5步中得到的庫的名字,在window下是"Sample1.dll",在unix下要加首碼"lib",即"libSample1.so"。
 
2.編譯java檔案:
javac  Sample1.java
    無錯產生Sample1.class檔案
3.產生C/C++標頭檔
javah  Sample1
    產生Sample1.h
使用命令 cat  Sample1.h 查看,內容為:

/* DO NOT EDIT THIS FILE - it is machine generated */<br />#include <jni.h><br />/* Header for class Sample1 */</p><p>#ifndef _Included_Sample1<br />#define _Included_Sample1<br />#ifdef __cplusplus<br />extern "C" {<br />#endif</p><p>JNIEXPORT jint JNICALL Java_Sample1_intMethod<br />(JNIEnv *, jobject, jint);</p><p>JNIEXPORT jboolean JNICALL Java_Sample1_booleanMethod<br />(JNIEnv *, jobject, jboolean);</p><p>JNIEXPORT jstring JNICALL Java_Sample1_stringMethod<br />(JNIEnv *, jobject, jstring);</p><p>JNIEXPORT jint JNICALL Java_Sample1_intArrayMethod<br />(JNIEnv *, jobject, jintArray);</p><p>#ifdef __cplusplus<br />}<br />#endif<br />#endif
 我們可以對比看看java檔案中對應的方法


 4.編寫C/C++代碼

   Sample1.c:

 #include "Sample1.h"<br /> #include <string.h><br /> JNIEXPORT jint JNICALL Java_Sample1_intMethod<br /> (JNIEnv *env, jobject obj, jint num) {<br /> return num * num;<br /> }<br /> JNIEXPORT jboolean JNICALL Java_Sample1_booleanMethod<br /> (JNIEnv *env, jobject obj, jboolean boolean) {<br /> return !boolean;<br /> }<br /> JNIEXPORT jstring JNICALL Java_Sample1_stringMethod<br /> (JNIEnv *env, jobject obj, jstring string) {<br /> const char *str = (*env)->GetStringUTFChars(env, strin<br /> char cap[128];<br /> strcpy(cap, str);<br /> (*env)->ReleaseStringUTFChars(env, string, str);<br /> return (*env)->NewStringUTF(env, strupr(cap));<br /> }<br /> JNIEXPORT jint JNICALL Java_Sample1_intArrayMethod<br /> (JNIEnv *env, jobject obj, jintArray array) {<br /> int i, sum = 0;<br /> jsize len = (*env)->GetArrayLength(env, array);<br /> jint *body = (*env)->GetIntArrayElements(env, array, 0<br /> for (i=0; i<len; i++)<br /> { sum += body[i];<br /> }<br /> (*env)->ReleaseIntArrayElements(env, array, body, 0);<br /> return sum;<br /> }<br /> void main(){}

Sample1.cpp:#include "Sample1.h"<br />#include <string.h><br />NIEXPORT jint JNICALL Java_Sample1_intMethod<br /> (JNIEnv *env, jobject obj, jint num) {<br /> return num * num;<br />}<br />JNIEXPORT jboolean JNICALL Java_Sample1_booleanMethod<br /> (JNIEnv *env, jobject obj, jboolean boolean) {<br /> return !boolean;<br />}<br />JNIEXPORT jstring JNICALL Java_Sample1_stringMethod<br /> (JNIEnv *env, jobject obj, jstring string) {<br /> const char *str = env->GetStringUTFChars(string, 0);<br /> char cap[128];<br /> strcpy(cap, str);<br /> env->ReleaseStringUTFChars(string, str);<br /> return env->NewStringUTF(strupr(cap));<br />}<br />JNIEXPORT jint JNICALL Java_Sample1_intArrayMethod<br /> (JNIEnv *env, jobject obj, jintArray array) {<br /> int i, sum = 0;<br /> jsize len = env->GetArrayLength(array);<br /> jint *body = env->GetIntArrayElements(array, 0);<br /> for (i=0; i<len; i++)<br /> { sum += body[i];<br /> }<br /> env->ReleaseIntArrayElements(array, body, 0);<br /> return sum;<br /> }<br /> void main(){}
兩個差別就是JNIEnv這個類
  C中使用 jsize len = (*env)->GetArrayLength(env,array);
  C++中使用 jsize len = env->GetArrayLength(env,array);  
 
5.產生共用庫檔案
 編譯Sample1.c檔案
 gcc -fPIC -D_REENTRANT -I/usr/lib/java/include -I/usr/lib/java/include/linux -c Sample1.c 
 編譯用到了jdk include中jni.h,include/linux中jni_md.h兩個標頭檔
 /usr/lib/java/include        是jin.h路徑
 /usr/lib/java/include、linux 是jni_md.h路徑
 此時產生Sampel.o檔案
 運行:
 gcc -shared Sample1.o -o libSample1.so
 產生libSample1.so


6.運行java程式
libSample1.so檔案拷貝到java的載入庫LD_LIBRARY_PATH指向的路徑中:
如果沒有足夠許可權,可以這樣:
(1).在/home下建立一個用來存放.so庫檔案的目錄,比如/home/xxx/lib
(2).把libSample1.so檔案拷貝到該目錄下
(3).運行:export LD_LIBRARY_PATH=/home/xxx/lib  (只在當前shall下有效...)
現在運行java Sample1
一切正常後,可以看到運行結果輸出:
intMethod: 25
booleanMethod: false
stringMethod: JAVA
intArrayMethod: 33
完成第一個JNI程式。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.