歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux編程 >> Linux編程

Linux下JNI的demo

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文件:

 
  1. public class Sample1  
  2.  {  
  3. public native int intMethod(int n);  
  4. public native boolean booleanMethod(boolean bool);  
  5. public native String stringMethod(String text);  
  6. public native int intArrayMethod(int[] intArray);  
  7.   
  8. public static void main(String[] args)  
  9. {  
  10. System.loadLibrary("Sample1");  
  11. Sample1 sample = new Sample1();  
  12. int square = sample.intMethod(5);  
  13. boolean bool = sample.booleanMethod(true);  
  14. String text = sample.stringMethod("JAVA");  
  15. int sum = sample.intArrayMethod(  
  16. new int[]{1,1,2,3,5,8,13} );  
  17.   
  18. System.out.println("intMethod: " + square);  
  19. System.out.println("booleanMethod: " + bool);  
  20. System.out.println("stringMethod: " + text);  
  21. System.out.println("intArrayMethod: " + sum);  
  22. }  
  23. }  
 兩個地方要注意,
 一。上面的方法都用到了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 查看,內容為:
  1.  /* DO NOT EDIT THIS FILE - it is machine generated */  
  2. #include <jni.h>   
  3. /* Header for class Sample1 */  
  4.   
  5. #ifndef _Included_Sample1   
  6. #define _Included_Sample1   
  7. #ifdef __cplusplus   
  8. extern "C" {  
  9. #endif   
  10.   
  11. JNIEXPORT jint JNICALL Java_Sample1_intMethod  
  12. (JNIEnv *, jobject, jint);  
  13.   
  14. JNIEXPORT jboolean JNICALL Java_Sample1_booleanMethod  
  15. (JNIEnv *, jobject, jboolean);  
  16.   
  17. JNIEXPORT jstring JNICALL Java_Sample1_stringMethod  
  18. (JNIEnv *, jobject, jstring);  
  19.   
  20. JNIEXPORT jint JNICALL Java_Sample1_intArrayMethod  
  21. (JNIEnv *, jobject, jintArray);  
  22.   
  23. #ifdef __cplusplus   
  24. }  
  25. #endif   
  26. #endif  
我們可以對比看看java文件中對應的方法
 4.編寫C/C++代碼

   Sample1.c:

  1. #include "Sample1.h"  
  2. #include <string.h>   
  3.  JNIEXPORT jint JNICALL Java_Sample1_intMethod  
  4.  (JNIEnv *env, jobject obj, jint num) {  
  5.  return num * num;  
  6.  }  
  7.  JNIEXPORT jboolean JNICALL Java_Sample1_booleanMethod  
  8.  (JNIEnv *env, jobject obj, jboolean boolean) {  
  9.  return !boolean;  
  10.  }  
  11.  JNIEXPORT jstring JNICALL Java_Sample1_stringMethod  
  12.  (JNIEnv *env, jobject obj, jstring string) {  
  13.  const char *str = (*env)->GetStringUTFChars(env, strin  
  14.  char cap[128];  
  15.  strcpy(cap, str);  
  16.  (*env)->ReleaseStringUTFChars(env, string, str);  
  17.  return (*env)->NewStringUTF(env, strupr(cap));  
  18.  }  
  19.  JNIEXPORT jint JNICALL Java_Sample1_intArrayMethod  
  20.  (JNIEnv *env, jobject obj, jintArray array) {  
  21.  int i, sum = 0;  
  22.  jsize len = (*env)->GetArrayLength(env, array);  
  23.  jint *body = (*env)->GetIntArrayElements(env, array, 0  
  24.  for (i=0; i<len; i++)  
  25.  { sum += body[i];  
  26.  }  
  27.  (*env)->ReleaseIntArrayElements(env, array, body, 0);  
  28.  return sum;  
  29.  }  
  30.  void  main(){}  

Sample1.cpp:

  1. #include "Sample1.h"   
  2. #include <string.h>   
  3. NIEXPORT jint JNICALL Java_Sample1_intMethod  
  4.  (JNIEnv *env, jobject obj, jint num) {  
  5.  return num * num;  
  6. }  
  7. JNIEXPORT jboolean JNICALL Java_Sample1_booleanMethod  
  8.  (JNIEnv *env, jobject obj, jboolean boolean) {  
  9.  return !boolean;  
  10. }  
  11. JNIEXPORT jstring JNICALL Java_Sample1_stringMethod  
  12.  (JNIEnv *env, jobject obj, jstring string) {  
  13.  const char *str = env->GetStringUTFChars(string, 0);  
  14.  char cap[128];  
  15.  strcpy(cap, str);  
  16.  env->ReleaseStringUTFChars(string, str);  
  17.  return env->NewStringUTF(strupr(cap));  
  18. }  
  19. JNIEXPORT jint JNICALL Java_Sample1_intArrayMethod  
  20.  (JNIEnv *env, jobject obj, jintArray array) {  
  21.  int i, sum = 0;  
  22.  jsize len = env->GetArrayLength(array);  
  23.  jint *body = env->GetIntArrayElements(array, 0);  
  24.  for (i=0; i<len; i++)  
  25.  { sum += body[i];  
  26.  }  
  27.  env->ReleaseIntArrayElements(array, body, 0);  
  28.  return sum;  
  29.  }  
  30.  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程序。

Copyright © Linux教程網 All Rights Reserved