zoukankan      html  css  js  c++  java
  • 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'';
    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 }
  • 相关阅读:
    <阿里工程师的自我素养>读后感-技术人应该具备的一些基本素质
    Hbase的基本原理(与HIVE的区别、数据结构模型、拓扑结构、水平分区原理、场景)
    大数据技术体系 && NoSQL数据库的基本原理
    软件测试面试经验
    APP非功能测试
    手机APP测试(测试点、测试流程、功能测试)
    性能测试学习之路 (四)jmeter 脚本开发实战(JDBC &JMS &接口脚本 & 轻量级接口自动化测试框架)
    HTML 实战生成一张页面
    前端性能测试(H5性能测试)
    JAVA基础——设计模式之观察者模式
  • 原文地址:https://www.cnblogs.com/liuling/p/2013-12-22.html
Copyright © 2011-2022 走看看