JNI調用的helloworld(JNI_OnLoad映射方式)


  本示例展示JNI的基本示例,helloworld級別的,不過是用JNI_OnLoad映射的方式。

  直接看代碼,先看包含native method的Person.java的代碼:

 1 package helloworld;
 2 
 3 /**
 4  * author : Zhou Shenshen
 5  * date   : 2016.7.16
 6  * desc   : It is a class to show how to use JNI.
 7  *          演示調用JNI本地方法的寫法和加載動態庫
 8  * email  : zhouss@iPanel.cn
 9  */
10 public class Person{
11 
12     /* Load the shared library libperson.so 加載C語言編寫的動態庫*/
13     static{
14         String classDir = Person.class.getResource("/").getPath(); 
15         System.load(classDir + "helloworld/libperson.so");
16     }
17 
18     /* Two native implemented by person.c 兩個native method通過person.c來實現 */
19     public native void show();
20     public native void say(String content);
21 }

 

 這里native method的定義不用多說,注意就是調用System的load時,傳入的參數是庫的全名,linux下包括lib和.so,而loadLibrary方法則是傳入庫的名字,沒有前后綴。這里采用絕對路徑定位和加載庫,不用在設定庫的參數。

  接下來看person.c的代碼:

 1 #include <jni.h>
 2 #include <stdio.h>
 3 
 4 /* Declare two function map to java native method 聲明映射過來的本地函數 */
 5 void native_show(JNIEnv * env,jobject obj);
 6 void native_say(JNIEnv * env,jobject obj,jstring string);
 7 
 8 /* The array to map java method and c function 映射用的JNINativeMethod數組 */
 9 static JNINativeMethod methods[] = {
10     {"show","()V",(void *)native_show},
11     {"say","(Ljava/lang/String;)V",(void *)native_say}
12 };
13 
14 /* This function will be exec when libperson.so been loading. */
15 JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM* vm, void* reserved){
16     JNIEnv * env = NULL;
17     jclass cls = NULL;
18     jint result = -1;
19     if((*vm)->GetEnv(vm,(void **)&env,JNI_VERSION_1_6) != JNI_OK){
20         printf("err!!");
21         return JNI_ERR;
22     }
23     cls = (*env)->FindClass(env,"helloworld/Person");  //通過類路徑字符串找到對應類
24     (*env)->RegisterNatives(env,cls,methods,sizeof(methods)/sizeof(JNINativeMethod));//調用RegisterNatives來注冊本地方法,完成映射
25     return JNI_VERSION_1_6;
26 }
27 
28 /* Define the c native function. 本地方法映射過來的實現*/
29 void native_show(JNIEnv * env,jobject obj){
30     printf("hello!!\n");
31 }
32 void native_say(JNIEnv * env,jobject obj,jstring string){
33     const char * str = (*env)->GetStringUTFChars(env,string,0); //將jstring轉成c語言中的字符串。
34     printf("content : %s\n",str);
35 }

  然后寫個主函數測試JNI調用的情況:

 1 package helloworld;
 2 /**
 3  * author : Zhou Shenshen
 4  * date   : 2016.7.16
 5  * desc   : As the entrance for the example.
 6  * email  : zhouss@iPanel.cn
 7  */
 8 public class Main{
 9     public static void main(String[] args){
10         Person p = new Person();
11         p.show();
12         p.say("I am XiaoMing!");
13     }
14 }

  編譯運行的腳本如下:

#!/bin/sh

#test the libperson.so is exist.
if [ -e libperson.so ];then
  #change to .. directory to run this example
  cd ..
  java  helloworld.Main
  exit 0;
fi

#Compiler *.java to *.class
javac Person.java Main.java
#Test the JAVA_HOME 
if [ $JAVA_HOME != ""  ]; then
  #Compiler *.c to *.o,then link to shared library *.so.
  gcc -fPIC -c -I$(echo $JAVA_HOME)/include/ -I$(echo $JAVA_HOME)/include/linux person.c
  gcc -shared -o libperson.so person.o
  #change to .. directory to run this example
  cd ..
  java helloworld.Main
  exit 0
else
  echo "JAVA_HOME is empty variable"
  exit 1
fi

  linux下bash下運行的結果如下:

hello!!
content : I am XiaoMing!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM