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[]= {"first",
    "second",
    "third",
    "fourth",
    "fifth"}; ret= (jobjectArray)env->NewObjectArray(,
    env->FindClass("java/lang/String"),
    env->NewStringUTF("")); for(i=;i<;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,-);
    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(,cls_array,); 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=;i<;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,-); 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,-); env->CallBooleanMethod(m_obj_list,m_mid_add,m_obj_result); return m_obj_list;
    }

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

JNI 对象处理 (转)的更多相关文章

  1. 【转】JNI 对象处理

    原文网址:http://leidiqiu.iteye.com/blog/720307 JNI 的基本问题就是解决 Java 和 C++ 代码互相调用的通信问题,在 C++ 代码编写过程中最大的问题莫过 ...

  2. JNI系列——PassData

    1.在工程目录下创建xxx.jni包并在该包下创建JNI类 2.在JNI类中声明所有的本地方法,并加载库 3.在MainActivity类中实例化JNI对象,并调用其方法 4.通过Javah生成的方法 ...

  3. 本地C代码中创建Java对象

    作者:唐老师,华清远见嵌入式学院讲师. 创建Java域的对象就是创建Java类的实例,再调用Java类的构造方法. 以Bitmap的构建为例,Bitmap中并没有Java对象创建的代码及外部能访问的构 ...

  4. 深入浅出 - Android系统移植与平台开发(九)- JNI介绍

    作者:唐老师,华清远见嵌入式学院讲师. JNI是在学习Android HAL时必须要面临一个知识点,如果你不了解它的机制,不了解它的使用方式,你会被本地代码绕的晕头转向,JNI作为一个中间语言的翻译官 ...

  5. 关于 调用 JNI JAR 的说明和注意事项,调用第三方 JAR SDK 和 翻译 安卓 JAVA 代码 的说明 V2015.6.10

    关于 调用 JNI JAR 的说明和注意事项,调用第三方 JAR SDK 和 翻译 安卓 JAVA 代码 的说明 V2015.6.10 转载请标明出处,否则死全家.选择[复制链接]即可得到出处. (* ...

  6. JNI介绍(转)

    源:JNI介绍 JNI是在学习Android HAL时必须要面临一个知识点,如果你不了解它的机制,不了解它的使用方式,你会被本地代码绕的晕头转向,JNI作为一个中间语言的翻译官在运行Java代码的An ...

  7. JNI 引用问题梳理(转)

    局部引用: JNI 函数内部创建的 jobject 对象及其子类( jclass . jstring . jarray 等) 对象都是局部引用,它们在 JNI 函数返回后无效: 一般情况下,我们应该依 ...

  8. JNI介绍

    JNI是在学习Android HAL时必须要面临一个知识点,如果你不了解它的机制,不了解它的使用方式,你会被本地代码绕的晕头转向,JNI作为一个中间语言的翻译官在运行Java代码的Android中有着 ...

  9. JNI基础知识

    JNI是在学习Android HAL时必须要面临一个知识点,假设你不了解它的机制,不了解它的使用方式,你会被本地代码绕的晕头转向,JNI作为一个中间语言的翻译官在运行Java代码的Android中有着 ...

随机推荐

  1. WebApi实现原理解析笔记

    这是我看过WebApi实现代码后的一些总结,一方面加深自己的记忆,另外也希望能够帮助大家更深入的了解WebApi. 注:暂时没有好好的整理,可能有些晦涩难懂. Webapi 控制器类必须实现IHttp ...

  2. Docker入门之四搭建私有仓库

    前面学习了下镜像和容器,今天来学习下仓库,来搭建本地私有仓库.当然可以使用远程的共有的仓库,但在企业中有的还是放在本地,所以需要搭建私有仓库. 一.搭建仓库 可以在容器中run一个仓库镜像. dock ...

  3. Codeforces Round #430 (Div. 2)

    A. Kirill And The Game time limit per test 2 seconds memory limit per test 256 megabytes input stand ...

  4. 从入门到精通之Boyer-Moore字符串搜索算法详解

    本文讲述的是Boyer-Moore算法,Boyer-Moore算法作为字符串搜索算法,兴趣之下就想了解这个算法,发现这个算法一开始还挺难理解的,也许是我理解能力不是很好吧,花了小半天才看懂,看懂了过后 ...

  5. php使用PHPMailer邮件类发送邮件

    PHPMailer是一个用于发送电子邮件的PHP函数包.它提供的功能包括:*.在发送邮时指定多个收件人,抄送地址,暗送地址和回复地址*.支持多种邮件编码包括:8bit,base64,binary和qu ...

  6. PE文件格式详解,第二讲,NT头文件格式,以及文件头格式

    PE文件格式详解,第二讲,NT头文件格式,以及文件头格式 作者:IBinary出处:http://www.cnblogs.com/iBinary/版权所有,欢迎保留原文链接进行转载:) PS:本篇博客 ...

  7. VNC实现Windows远程访问Ubuntu 16.04(无需安装第三方桌面)

    本文主要是讲解如果理由VNC实现Windows远程访问Ubuntu 16.04,其实网上有很多类似教程,但是很多需要安装第三方桌面(xfce桌面等等),而且很多人不太喜欢安装第三方桌面,很多人像笔者一 ...

  8. zoj3321 circle floyd 最小生成树

    Circle 断一个图是否是一个环. 思路:必有m==n,那么我们用n-1条边能够生成一棵树(即是所有点联通,则用floyd即可),然后看最后一条边的两个点是否是单边(度为一)即可 . #includ ...

  9. Java命令模式以及来自lambda的优化

    前言    设计模式是软件工程中一些问题的统一解决方案的模型,它的出现是为了解决一些普遍存在的,却不能被语言特性直接解决的问题,随着软件工程的发展,设计模式也会不断的进行更新,本文介绍的是经典设计模式 ...

  10. 如何抽象一个 Vue 公共组件

    之前一直想写一篇关于抽象 Vue 组件的随笔,无奈一直没想到好的例子.恰巧最近为公司项目做了一个数字键盘的组件,于是就以这个为例聊聊如何抽象 Vue 的组件. 先上 Demo 与 源码.(demo最好 ...