• JNI 对象处理 (转)


    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
      package com.ldq.list;
      
      import java.util.List;
      
      public class ExList {
      
          /**
           * @param args
           */
          public static void main(String[] args) {
              // TODO Auto-generated method stub
              System.out.println("-------WifiManager.test()");
              System.out.println(WifiManager.test());
      
              System.out.println("-------WifiManager.testArray()");
              String[] s1 = WifiManager.testArray();
              for (int i = 0; i < s1.length; i++) {
                  System.out.println(s1[i]);
              }
      
              System.out.println("-------WifiManager.testObject()");
              System.out.println(WifiManager.testObject().ssid);
              System.out.println(WifiManager.testObject().mac);
              System.out.println(WifiManager.testObject().level);
      
              System.out.println("-------WifiManager.getScanResultsA()");
              ScanResult[] s2 = WifiManager.getScanResultsA();
              for (int i = 0; i < s2.length; i++) {
                  System.out.println(s2[i].ssid);
                  System.out.println(s2[i].mac);
                  System.out.println(s2[i].level);
              }
      
              System.out.println("-------WifiManager.getScanResults()");
              List<ScanResult> list = WifiManager.getScanResults();
              System.out.println(list.get(0).ssid);
              System.out.println(list.get(0).mac);
              System.out.println(list.get(0).level);
      
          }
      }
    • ScanResult.java
      package com.ldq.list;
      
      public class ScanResult {
          String ssid;
          String mac;
          int level;
      
          public ScanResult() {
          }
      
          public ScanResult(String ssid, String mac, int level) {
              this.ssid = ssid;
              this.mac = mac;
              this.level = level;
          }
      }
    • WifiManager.java
      package com.ldq.list;
      
      import java.util.List;
      
      public class WifiManager {
      
          static {
              System.loadLibrary("wifi");
          }
      
          public native static String test();
      
          public native static String[] testArray();
      
          public native static ScanResult testObject();
      
          public native static ScanResult[] getScanResultsA();
      
          public native static List<ScanResult> getScanResults();
      }
    • wifi.cpp
      #include <jni.h>
      #include "com_ldq_list_WifiManager.h"
      
      /*
       * Class:     com_ldq_list_WifiManager
       * Method:    test
       * Signature: ()Ljava/lang/String;
       */
      JNIEXPORT jstring JNICALL Java_com_ldq_list_WifiManager_test (JNIEnv *env, jclass cls)
      {
          return env->NewStringUTF("hello");
      }
      
      /*
       * Class:     com_ldq_list_WifiManager
       * Method:    testArray
       * Signature: ()[Ljava/lang/String;
       */
      JNIEXPORT jobjectArray JNICALL Java_com_ldq_list_WifiManager_testArray (JNIEnv *env, jclass cls)
      {
          jobjectArray ret;
          int i;
      
          char *message[5]= {"first", 
          "second", 
          "third", 
          "fourth", 
          "fifth"};
      
          ret= (jobjectArray)env->NewObjectArray(5,
               env->FindClass("java/lang/String"),
               env->NewStringUTF(""));
      
          for(i=0;i<5;i++) {
              env->SetObjectArrayElement(
              ret,i,env->NewStringUTF(message[i]));
          }
          return(ret);
      
      }
      
      /*
       * Class:     com_ldq_list_WifiManager
       * Method:    testObject
       * Signature: ()Lcom/ldq/list/ScanResult;
       */
      JNIEXPORT jobject JNICALL Java_com_ldq_list_WifiManager_testObject (JNIEnv *env, jclass cls)
      {
          jclass m_cls  = env->FindClass("com/ldq/list/ScanResult");
          jmethodID mid = env->GetMethodID(m_cls,"<init>","()V");
          jobject obj   = env->NewObject(m_cls,mid);
      
          jfieldID fid_ssid  = env->GetFieldID(m_cls,"ssid","Ljava/lang/String;");
          jfieldID fid_mac   = env->GetFieldID(m_cls,"mac","Ljava/lang/String;");
          jfieldID fid_level = env->GetFieldID(m_cls,"level","I");
      
                               env->SetObjectField(obj,fid_ssid,env->NewStringUTF("AP1"));
                               env->SetObjectField(obj,fid_mac,env->NewStringUTF("00-11-22-33-44-55"));
                               env->SetIntField(obj,fid_level,-66);
          return obj;
      }
      
      /*
       * Class:     com_ldq_list_WifiManager
       * Method:    getScanResultsA
       * Signature: ()[Lcom/ldq/list/ScanResult;
       */
      JNIEXPORT jobjectArray JNICALL Java_com_ldq_list_WifiManager_getScanResultsA (JNIEnv *env, jclass cls)
      {
          jclass cls_array=env->FindClass("java/lang/Object");
          jobjectArray obj_array=env->NewObjectArray(2,cls_array,0);
      
          jclass cls_obj = env->FindClass("com/ldq/list/ScanResult");
          jmethodID m    = env->GetMethodID(cls_obj,"<init>","()V");
      
          jfieldID fid_ssid  = env->GetFieldID(cls_obj,"ssid","Ljava/lang/String;");
          jfieldID fid_mac   = env->GetFieldID(cls_obj,"mac","Ljava/lang/String;");
          jfieldID fid_level = env->GetFieldID(cls_obj,"level","I");
      
          for(int i=0;i<2;i++)
          {
              jobject obj=env->NewObject(cls_obj,m);
      
              jobject o1=env->NewStringUTF("AP2");
              env->SetObjectField(obj,fid_ssid,o1);
      
              jobject o2=env->NewStringUTF("22-22-22-22-22-22");
              env->SetObjectField(obj,fid_mac,o2);
      
              env->SetIntField(obj,fid_level,-66);
      
              env->SetObjectArrayElement(obj_array,i,obj);
          }
          return obj_array;
      }
      
      /*
       * Class:     com_ldq_list_WifiManager
       * Method:    getScanResults
       * Signature: ()Ljava/util/List;
       */
      JNIEXPORT jobject JNICALL Java_com_ldq_list_WifiManager_getScanResults (JNIEnv *env, jclass cls)
      {
          jclass m_cls_list    = env->FindClass("java/util/ArrayList");
          jmethodID m_mid_list = env->GetMethodID(m_cls_list,"<init>","()V");
          jobject m_obj_list   = env->NewObject(m_cls_list,m_mid_list);
      
          jmethodID m_mid_add  = env->GetMethodID(m_cls_list,"add","(Ljava/lang/Object;)Z");
      
          jclass m_cls_result    = env->FindClass("com/ldq/list/ScanResult");
          jmethodID m_mid_result = env->GetMethodID(m_cls_result,"<init>","()V");
          jobject m_obj_result   = env->NewObject(m_cls_result,m_mid_result);
      
          jfieldID m_fid_1 = env->GetFieldID(m_cls_result,"ssid","Ljava/lang/String;");
          jfieldID m_fid_2 = env->GetFieldID(m_cls_result,"mac","Ljava/lang/String;");
          jfieldID m_fid_3 = env->GetFieldID(m_cls_result,"level","I");
      
          env->SetObjectField(m_obj_result,m_fid_1,env->NewStringUTF("AP6"));
          env->SetObjectField(m_obj_result,m_fid_2,env->NewStringUTF("66-66-66-66-66-66"));
          env->SetIntField(m_obj_result,m_fid_3,-66);
      
          env->CallBooleanMethod(m_obj_list,m_mid_add,m_obj_result);
      
          return m_obj_list;
      }

      转自:http://leidiqiu.iteye.com/blog/720307

  • 相关阅读:
    php省市联动实现
    json学习笔记
    ajax无刷新技术
    session和cookie
    缩略图,透明度,水印,图片合并
    PHP画矩形,椭圆,圆,画椭圆弧 ,饼状图
    PHP字母数字验证码和中文验证码
    PHP画图的基本步骤GD库
    文件上传和多文件上传
    js身份证验证
  • 原文地址:https://www.cnblogs.com/chensheng-zhou/p/JNI.html
Copyright © 2020-2023  润新知