• 【转】JNI 对象处理


    原文网址:http://leidiqiu.iteye.com/blog/720307

    JNI 的基本问题就是解决 Java 和 C++ 代码互相调用的通信问题,在 C++ 代码编写过程中最大的问题莫过于适应其中的代码编写规则,C++调用或是返回的内容必须遵守 JVM 和 C++ 代码的通信规则。

    C++ 调用 Java 的一般步骤如下:

    • 获得类:
      • jclass cls          = env->FindClass("com/ldq/Student");
      • cls 可认为是类的句柄
      • "com/ldq/Student" 就是类文件,注意不能用 "com.ldq.Student"
    • 获得方法:
      • jmethodID mid = env->GetMethodID(cls,"<init>","()V");
      • 以上为构造函数,参数是 "<init>" "()V"
      • jmethodID mid = env->GetMethodID(cls,"getAge","()I");
      • 以上为类的方法,第一个参数是类句柄,第二个参数是方法名字,第三个参数是签名标识 

    Java类型

    符号
    boolean

    byte

    char

    C  
    short
    int
    long L  
    float F  

    double

    D  

    void

    objects对象 Lfully-qualified-class-name;        L类名;
    Arrays数组 [array-type [数组类型 
    methods方法                  (argument-types)return-type(参数类型)返回类型 
    • 获得对象:
      • jobject obj=env->NewObject(cls,mid);
      • 以上便获得了一个对象的句柄
    • 获得对象成员变量:
      • jfieldID fid=env->GetFieldID(cls,"age","I");
      • 以上和获得类方法差不多
    • 操作成员变量:
      • jint a=env->GetIntField(obj,mid);
      • age=age+10;
      • env->SetIntField(obj,fid,a);
    • 返回:
      • return obj;

    下面是本人练习的例子

    • ExList.java
    Java代码  
    1. package com.ldq.list;  
    2.   
    3. import java.util.List;  
    4.   
    5. public class ExList {  
    6.   
    7.     /** 
    8.      * @param args 
    9.      */  
    10.     public static void main(String[] args) {  
    11.         // TODO Auto-generated method stub  
    12.         System.out.println("-------WifiManager.test()");  
    13.         System.out.println(WifiManager.test());  
    14.   
    15.         System.out.println("-------WifiManager.testArray()");  
    16.         String[] s1 = WifiManager.testArray();  
    17.         for (int i = 0; i < s1.length; i++) {  
    18.             System.out.println(s1[i]);  
    19.         }  
    20.   
    21.         System.out.println("-------WifiManager.testObject()");  
    22.         System.out.println(WifiManager.testObject().ssid);  
    23.         System.out.println(WifiManager.testObject().mac);  
    24.         System.out.println(WifiManager.testObject().level);  
    25.   
    26.         System.out.println("-------WifiManager.getScanResultsA()");  
    27.         ScanResult[] s2 = WifiManager.getScanResultsA();  
    28.         for (int i = 0; i < s2.length; i++) {  
    29.             System.out.println(s2[i].ssid);  
    30.             System.out.println(s2[i].mac);  
    31.             System.out.println(s2[i].level);  
    32.         }  
    33.   
    34.         System.out.println("-------WifiManager.getScanResults()");  
    35.         List<ScanResult> list = WifiManager.getScanResults();  
    36.         System.out.println(list.get(0).ssid);  
    37.         System.out.println(list.get(0).mac);  
    38.         System.out.println(list.get(0).level);  
    39.   
    40.     }  
    41. }  
    • ScanResult.java
    Java代码  
    1. package com.ldq.list;  
    2.   
    3. public class ScanResult {  
    4.     String ssid;  
    5.     String mac;  
    6.     int level;  
    7.   
    8.     public ScanResult() {  
    9.     }  
    10.   
    11.     public ScanResult(String ssid, String mac, int level) {  
    12.         this.ssid = ssid;  
    13.         this.mac = mac;  
    14.         this.level = level;  
    15.     }  
    16. }  
    • WifiManager.java
    Java代码  
    1. package com.ldq.list;  
    2.   
    3. import java.util.List;  
    4.   
    5. public class WifiManager {  
    6.   
    7.     static {  
    8.         System.loadLibrary("wifi");  
    9.     }  
    10.   
    11.     public native static String test();  
    12.   
    13.     public native static String[] testArray();  
    14.   
    15.     public native static ScanResult testObject();  
    16.   
    17.     public native static ScanResult[] getScanResultsA();  
    18.   
    19.     public native static List<ScanResult> getScanResults();  
    20. }  
    • wifi.cpp
    Cpp代码  
    1. #include <jni.h>  
    2. #include "com_ldq_list_WifiManager.h"  
    3.   
    4. /* 
    5.  * Class:     com_ldq_list_WifiManager 
    6.  * Method:    test 
    7.  * Signature: ()Ljava/lang/String; 
    8.  */  
    9. JNIEXPORT jstring JNICALL Java_com_ldq_list_WifiManager_test (JNIEnv *env, jclass cls)  
    10. {  
    11.     return env->NewStringUTF("hello");  
    12. }  
    13.   
    14. /* 
    15.  * Class:     com_ldq_list_WifiManager 
    16.  * Method:    testArray 
    17.  * Signature: ()[Ljava/lang/String; 
    18.  */  
    19. JNIEXPORT jobjectArray JNICALL Java_com_ldq_list_WifiManager_testArray (JNIEnv *env, jclass cls)  
    20. {  
    21.     jobjectArray ret;  
    22.     int i;  
    23.   
    24.     char *message[5]= {"first",   
    25.     "second",   
    26.     "third",   
    27.     "fourth",   
    28.     "fifth"};  
    29.   
    30.     ret= (jobjectArray)env->NewObjectArray(5,  
    31.          env->FindClass("java/lang/String"),  
    32.          env->NewStringUTF(""));  
    33.   
    34.     for(i=0;i<5;i++) {  
    35.         env->SetObjectArrayElement(  
    36.         ret,i,env->NewStringUTF(message[i]));  
    37.     }  
    38.     return(ret);  
    39.   
    40. }  
    41.   
    42. /* 
    43.  * Class:     com_ldq_list_WifiManager 
    44.  * Method:    testObject 
    45.  * Signature: ()Lcom/ldq/list/ScanResult; 
    46.  */  
    47. JNIEXPORT jobject JNICALL Java_com_ldq_list_WifiManager_testObject (JNIEnv *env, jclass cls)  
    48. {  
    49.     jclass m_cls  = env->FindClass("com/ldq/list/ScanResult");  
    50.     jmethodID mid = env->GetMethodID(m_cls,"<init>","()V");  
    51.     jobject obj   = env->NewObject(m_cls,mid);  
    52.   
    53.     jfieldID fid_ssid  = env->GetFieldID(m_cls,"ssid","Ljava/lang/String;");  
    54.     jfieldID fid_mac   = env->GetFieldID(m_cls,"mac","Ljava/lang/String;");  
    55.     jfieldID fid_level = env->GetFieldID(m_cls,"level","I");  
    56.   
    57.                          env->SetObjectField(obj,fid_ssid,env->NewStringUTF("AP1"));  
    58.                          env->SetObjectField(obj,fid_mac,env->NewStringUTF("00-11-22-33-44-55"));  
    59.                          env->SetIntField(obj,fid_level,-66);  
    60.     return obj;  
    61. }  
    62.   
    63. /* 
    64.  * Class:     com_ldq_list_WifiManager 
    65.  * Method:    getScanResultsA 
    66.  * Signature: ()[Lcom/ldq/list/ScanResult; 
    67.  */  
    68. JNIEXPORT jobjectArray JNICALL Java_com_ldq_list_WifiManager_getScanResultsA (JNIEnv *env, jclass cls)  
    69. {  
    70.     jclass cls_array=env->FindClass("java/lang/Object");  
    71.     jobjectArray obj_array=env->NewObjectArray(2,cls_array,0);  
    72.   
    73.     jclass cls_obj = env->FindClass("com/ldq/list/ScanResult");  
    74.     jmethodID m    = env->GetMethodID(cls_obj,"<init>","()V");  
    75.   
    76.     jfieldID fid_ssid  = env->GetFieldID(cls_obj,"ssid","Ljava/lang/String;");  
    77.     jfieldID fid_mac   = env->GetFieldID(cls_obj,"mac","Ljava/lang/String;");  
    78.     jfieldID fid_level = env->GetFieldID(cls_obj,"level","I");  
    79.   
    80.     for(int i=0;i<2;i++)  
    81.     {  
    82.         jobject obj=env->NewObject(cls_obj,m);  
    83.   
    84.         jobject o1=env->NewStringUTF("AP2");  
    85.         env->SetObjectField(obj,fid_ssid,o1);  
    86.   
    87.         jobject o2=env->NewStringUTF("22-22-22-22-22-22");  
    88.         env->SetObjectField(obj,fid_mac,o2);  
    89.   
    90.         env->SetIntField(obj,fid_level,-66);  
    91.   
    92.         env->SetObjectArrayElement(obj_array,i,obj);  
    93.     }  
    94.     return obj_array;  
    95. }  
    96.   
    97. /* 
    98.  * Class:     com_ldq_list_WifiManager 
    99.  * Method:    getScanResults 
    100.  * Signature: ()Ljava/util/List; 
    101.  */  
    102. JNIEXPORT jobject JNICALL Java_com_ldq_list_WifiManager_getScanResults (JNIEnv *env, jclass cls)  
    103. {  
    104.     jclass m_cls_list    = env->FindClass("java/util/ArrayList");  
    105.     jmethodID m_mid_list = env->GetMethodID(m_cls_list,"<init>","()V");  
    106.     jobject m_obj_list   = env->NewObject(m_cls_list,m_mid_list);  
    107.   
    108.     jmethodID m_mid_add  = env->GetMethodID(m_cls_list,"add","(Ljava/lang/Object;)Z");  
    109.   
    110.     jclass m_cls_result    = env->FindClass("com/ldq/list/ScanResult");  
    111.     jmethodID m_mid_result = env->GetMethodID(m_cls_result,"<init>","()V");  
    112.     jobject m_obj_result   = env->NewObject(m_cls_result,m_mid_result);  
    113.   
    114.     jfieldID m_fid_1 = env->GetFieldID(m_cls_result,"ssid","Ljava/lang/String;");  
    115.     jfieldID m_fid_2 = env->GetFieldID(m_cls_result,"mac","Ljava/lang/String;");  
    116.     jfieldID m_fid_3 = env->GetFieldID(m_cls_result,"level","I");  
    117.   
    118.     env->SetObjectField(m_obj_result,m_fid_1,env->NewStringUTF("AP6"));  
    119.     env->SetObjectField(m_obj_result,m_fid_2,env->NewStringUTF("66-66-66-66-66-66"));  
    120.     env->SetIntField(m_obj_result,m_fid_3,-66);  
    121.   
    122.     env->CallBooleanMethod(m_obj_list,m_mid_add,m_obj_result);  
    123.   
    124.     return m_obj_list;  
    125. }  
  • 相关阅读:
    Machine Learning Methods: Decision trees and forests
    The mean shift clustering algorithm
    Google Protocol Buffer 的使用和原理
    VS2013配置Caffe卷积神经网络工具(64位Windows 7)——准备依赖库
    测天之梯——2010年爱因斯坦讲座公众数学演讲《宇宙距离之梯》
    概率论复习 – 基础概率分布
    Conjugate prior relationships
    PRML Chapter 2. Probability Distributions
    PRML Chapter 1. Introduction
    POJ 2115 C Looooops(扩展欧几里得应用)
  • 原文地址:https://www.cnblogs.com/wi100sh/p/5172288.html
Copyright © 2020-2023  润新知