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
2 #includecom_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!”<12 // cout<<”successful”<
13 /

14 jfieldID field_a = env->GetFieldID(hello_clazz,”a”,”I”); //得到字段a的ID
15 jint a = env->GetIntField(obj,field_a); //得到字段a的值
16 cout<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<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
3 #include<string>
4 #include
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 #includecom_test_TestArray.h
2 #include
3 #include
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;i15 cout<16 }
17 /
18 // env->ReleaseIntArrayElements(jint_array,int_arr,JNI_ABORT);//JNI_ABORT:释放C++数组,但是不更新到Java
19 }