歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux編程 >> Linux編程 >> Linux下JNI的demo

Linux下JNI的demo

日期:2017/3/1 10:55:36   编辑:Linux編程
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. public static void main(String[] args)
  8. {
  9. System.loadLibrary("Sample1");
  10. Sample1 sample = new Sample1();
  11. int square = sample.intMethod(5);
  12. boolean bool = sample.booleanMethod(true);
  13. String text = sample.stringMethod("JAVA");
  14. int sum = sample.intArrayMethod(
  15. new int[]{1,1,2,3,5,8,13} );
  16. System.out.println("intMethod: " + square);
  17. System.out.println("booleanMethod: " + bool);
  18. System.out.println("stringMethod: " + text);
  19. System.out.println("intArrayMethod: " + sum);
  20. }
  21. }
兩個地方要注意,
一。上面的方法都用到了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. #ifndef _Included_Sample1
  5. #define _Included_Sample1
  6. #ifdef __cplusplus
  7. extern "C" {
  8. #endif
  9. JNIEXPORT jint JNICALL Java_Sample1_intMethod
  10. (JNIEnv *, jobject, jint);
  11. JNIEXPORT jboolean JNICALL Java_Sample1_booleanMethod
  12. (JNIEnv *, jobject, jboolean);
  13. JNIEXPORT jstring JNICALL Java_Sample1_stringMethod
  14. (JNIEnv *, jobject, jstring);
  15. JNIEXPORT jint JNICALL Java_Sample1_intArrayMethod
  16. (JNIEnv *, jobject, jintArray);
  17. #ifdef __cplusplus
  18. }
  19. #endif
  20. #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