JNI學習小結


Java中類型與C/C++中對應關系
 
Java中的類的對應
 
Sign簽名, 用來識別對應各個方法。
JDK下的javap.exe能輸出簽名。用法javap -s -p 完整類名
 
 

  下面是幾個例子程序:

1、C++本地方法中獲取Java中的變量以及調用Java中的方法

  Java代碼:

 1 package com.test;
 2 
 3 import java.util.Date;
 4 
 5 public class TestNative {
 6     public native void sayHello();
 7     private int a = 10;
 8     public int function(int x,Date date,int[] y){
 9         System.out.println("function");
10         return 0;
11     }
12     public double max(double a,double b){
13         return a>b?a:b;
14     }
15     /**
16      * @param args
17      */
18     public static void main(String[] args) {
19         System.loadLibrary("NativeCode");
20         TestNative tNative = new TestNative();
21         tNative.sayHello();
22     }
23 
24 }

  C++本地代碼:

  com_test_TestNative.h代碼省略了

 1 #include<iostream.h>
 2 #include"com_test_TestNative.h"
 3 
 4 JNIEXPORT void JNICALL Java_com_test_TestNative_sayHello(JNIEnv *env, jobject obj)
 5 {
 6     //因為sayHello不是靜態函數,所以傳進來的obj就是調用這個函數的對象,否則就是傳入native方法所在的類
 7     jclass hello_clazz = env->GetObjectClass(obj); //得到的就是native方法所在的類
 8 //    jfieldID fieldId_a = env->GetFieldID(hello_clazz,"a","I");
 9 //    jmethodID methodId_fun = env->GetMethodID(hello_clazz,"function","(ILjava/util/Date;[I)I");
10 //    env->CallIntMethod(obj,methodId_fun,0L,NULL,NULL); //方法調用
11 //    cout<<"hello world!"<<endl;
12 //    cout<<"successful"<<endl;
13 /*
14     jfieldID field_a = env->GetFieldID(hello_clazz,"a","I");  //得到字段a的ID
15     jint a = env->GetIntField(obj,field_a);   //得到字段a的值
16     cout<<a<<endl;
17     env->SetIntField(obj,field_a,100L);
18 */
19     jmethodID methodId_max = env->GetMethodID(hello_clazz,"max","(DD)D");
20     jvalue *values = new jvalue[2];  //jvalue是用來向java函數中傳參數的
21     values[0].d = 3.14;
22     values[1].d = 3.22;
23     //jdouble max = env->CallDoubleMethod(obj,methodId_max,3.18,3.15); //第一種方法調用
24     jdouble max = env->CallDoubleMethodA(obj,methodId_max,values); //第二種方法調用
25     delete [] values;
26     cout<<max<<endl;
27 
28 }


2、C++本地方法中對Java中的字符串操作(實現用戶輸入一個字符串,在C++中對其反轉)

  Java代碼:

 1 package com.test;
 2 
 3 import java.io.BufferedReader;
 4 import java.io.IOException;
 5 import java.io.InputStreamReader;
 6 
 7 public class TestStr {
 8     public native void cppCode();
 9     private String message;
10     public static void main(String[] args) throws IOException {
11         System.loadLibrary("CPP");
12         BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
13         String str = reader.readLine();
14         TestStr obj = new TestStr();
15         obj.message = str;
16         obj.cppCode();
17         System.out.println("java :"+obj.message);
18     }
19 
20 }

  c++本地方法:

  com_test_TestStr.h省略了

 1 #include "com_test_TestStr.h"
 2 #include<windows.h>
 3 #include<string>
 4 #include<algorithm>
 5 using namespace std;
 6 JNIEXPORT void JNICALL Java_com_test_TestStr_cppCode(JNIEnv *env, jobject obj)
 7 {
 8     jfieldID fid_msg = env->GetFieldID(env->GetObjectClass(obj),"message","Ljava/lang/String;");
 9     jstring j_msg = (jstring)env->GetObjectField(obj,fid_msg);
10     jsize len = env->GetStringLength(j_msg);   //得到字符串的長度
11     jchar* jstr = new jchar[len+1];    //申請空間
12     jstr[len] = L'\0';
13     env->GetStringRegion(j_msg,0,len,jstr);
14     //env->ReleaseStringChars(j_msg,jstr);
15     //MessageBoxW(NULL,(const wchar_t*)jstr,L"Title",MB_OK);
16     wstring wstr((const wchar_t*)jstr);
17     delete[] jstr;  //釋放空間
18     std::reverse(wstr.begin(),wstr.end());  //字符串反轉
19     jstring j_new_str = env->NewString((const jchar*)wstr.c_str(),(jint)wstr.size());   //創建一個新的字符串
20     env->SetObjectField(obj,fid_msg,j_new_str);  //設置字符串給java對象
21 
22 }

 

3、C++本地方法中獲取Java中的數組(實現用C++本地方法將Java中的數組排序)

  Java代碼:

 1 package com.test;
 2 
 3 public class TestArray {
 4 
 5     public int[] array = {5,7,3,4,1,9,2,8,6,0};
 6     
 7     public native void callCppFun();
 8     
 9     public static void main(String[] args) {
10         System.loadLibrary("TestArray");
11         TestArray obj = new TestArray();
12         obj.callCppFun();
13         for(int a:obj.array){
14             System.out.println(a);
15         }
16     }
17 
18 }

  C++本地代碼:

  com_test_TestArray.h省略了

 1 #include"com_test_TestArray.h"
 2 #include<iostream>
 3 #include<algorithm>
 4 using namespace std;
 5 JNIEXPORT void JNICALL Java_com_test_TestArray_callCppFun (JNIEnv *env, jobject obj)
 6 {
 7     jfieldID fid_array = env->GetFieldID(env->GetObjectClass(obj),"array","[I"); //獲取數組的id
 8     jintArray jint_array = (jintArray)env->GetObjectField(obj,fid_array);   
 9 
10     jint* int_arr = env->GetIntArrayElements(jint_array,NULL); //轉化為jint數組
11     jsize len = env->GetArrayLength(jint_array);
12     std::sort(int_arr,int_arr+len);  //對數組進行排序
13     env->ReleaseIntArrayElements(jint_array,int_arr,0); //0:釋放C++數組,並且更新到Java
14 /*    for(jsize i=0;i<len;i++){
15         cout<<int_arr[i]<<endl;
16     }
17 */
18  //   env->ReleaseIntArrayElements(jint_array,int_arr,JNI_ABORT);//JNI_ABORT:釋放C++數組,但是不更新到Java  
19 }

 


免責聲明!

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



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