原文网址: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
  1. package com.ldq.list;
  2. import java.util.List;
  3. public class ExList {
  4. /**
  5. * @param args
  6. */
  7. public static void main(String[] args) {
  8. // TODO Auto-generated method stub
  9. System.out.println("-------WifiManager.test()");
  10. System.out.println(WifiManager.test());
  11. System.out.println("-------WifiManager.testArray()");
  12. String[] s1 = WifiManager.testArray();
  13. for (int i = 0; i < s1.length; i++) {
  14. System.out.println(s1[i]);
  15. }
  16. System.out.println("-------WifiManager.testObject()");
  17. System.out.println(WifiManager.testObject().ssid);
  18. System.out.println(WifiManager.testObject().mac);
  19. System.out.println(WifiManager.testObject().level);
  20. System.out.println("-------WifiManager.getScanResultsA()");
  21. ScanResult[] s2 = WifiManager.getScanResultsA();
  22. for (int i = 0; i < s2.length; i++) {
  23. System.out.println(s2[i].ssid);
  24. System.out.println(s2[i].mac);
  25. System.out.println(s2[i].level);
  26. }
  27. System.out.println("-------WifiManager.getScanResults()");
  28. List<ScanResult> list = WifiManager.getScanResults();
  29. System.out.println(list.get(0).ssid);
  30. System.out.println(list.get(0).mac);
  31. System.out.println(list.get(0).level);
  32. }
  33. }
  • ScanResult.java
  1. package com.ldq.list;
  2. public class ScanResult {
  3. String ssid;
  4. String mac;
  5. int level;
  6. public ScanResult() {
  7. }
  8. public ScanResult(String ssid, String mac, int level) {
  9. this.ssid = ssid;
  10. this.mac = mac;
  11. this.level = level;
  12. }
  13. }
  • WifiManager.java
  1. package com.ldq.list;
  2. import java.util.List;
  3. public class WifiManager {
  4. static {
  5. System.loadLibrary("wifi");
  6. }
  7. public native static String test();
  8. public native static String[] testArray();
  9. public native static ScanResult testObject();
  10. public native static ScanResult[] getScanResultsA();
  11. public native static List<ScanResult> getScanResults();
  12. }
  • wifi.cpp
  1. #include <jni.h>
  2. #include "com_ldq_list_WifiManager.h"
  3. /*
  4. * Class:     com_ldq_list_WifiManager
  5. * Method:    test
  6. * Signature: ()Ljava/lang/String;
  7. */
  8. JNIEXPORT jstring JNICALL Java_com_ldq_list_WifiManager_test (JNIEnv *env, jclass cls)
  9. {
  10. return env->NewStringUTF("hello");
  11. }
  12. /*
  13. * Class:     com_ldq_list_WifiManager
  14. * Method:    testArray
  15. * Signature: ()[Ljava/lang/String;
  16. */
  17. JNIEXPORT jobjectArray JNICALL Java_com_ldq_list_WifiManager_testArray (JNIEnv *env, jclass cls)
  18. {
  19. jobjectArray ret;
  20. int i;
  21. char *message[5]= {"first",
  22. "second",
  23. "third",
  24. "fourth",
  25. "fifth"};
  26. ret= (jobjectArray)env->NewObjectArray(5,
  27. env->FindClass("java/lang/String"),
  28. env->NewStringUTF(""));
  29. for(i=0;i<5;i++) {
  30. env->SetObjectArrayElement(
  31. ret,i,env->NewStringUTF(message[i]));
  32. }
  33. return(ret);
  34. }
  35. /*
  36. * Class:     com_ldq_list_WifiManager
  37. * Method:    testObject
  38. * Signature: ()Lcom/ldq/list/ScanResult;
  39. */
  40. JNIEXPORT jobject JNICALL Java_com_ldq_list_WifiManager_testObject (JNIEnv *env, jclass cls)
  41. {
  42. jclass m_cls  = env->FindClass("com/ldq/list/ScanResult");
  43. jmethodID mid = env->GetMethodID(m_cls,"<init>","()V");
  44. jobject obj   = env->NewObject(m_cls,mid);
  45. jfieldID fid_ssid  = env->GetFieldID(m_cls,"ssid","Ljava/lang/String;");
  46. jfieldID fid_mac   = env->GetFieldID(m_cls,"mac","Ljava/lang/String;");
  47. jfieldID fid_level = env->GetFieldID(m_cls,"level","I");
  48. env->SetObjectField(obj,fid_ssid,env->NewStringUTF("AP1"));
  49. env->SetObjectField(obj,fid_mac,env->NewStringUTF("00-11-22-33-44-55"));
  50. env->SetIntField(obj,fid_level,-66);
  51. return obj;
  52. }
  53. /*
  54. * Class:     com_ldq_list_WifiManager
  55. * Method:    getScanResultsA
  56. * Signature: ()[Lcom/ldq/list/ScanResult;
  57. */
  58. JNIEXPORT jobjectArray JNICALL Java_com_ldq_list_WifiManager_getScanResultsA (JNIEnv *env, jclass cls)
  59. {
  60. jclass cls_array=env->FindClass("java/lang/Object");
  61. jobjectArray obj_array=env->NewObjectArray(2,cls_array,0);
  62. jclass cls_obj = env->FindClass("com/ldq/list/ScanResult");
  63. jmethodID m    = env->GetMethodID(cls_obj,"<init>","()V");
  64. jfieldID fid_ssid  = env->GetFieldID(cls_obj,"ssid","Ljava/lang/String;");
  65. jfieldID fid_mac   = env->GetFieldID(cls_obj,"mac","Ljava/lang/String;");
  66. jfieldID fid_level = env->GetFieldID(cls_obj,"level","I");
  67. for(int i=0;i<2;i++)
  68. {
  69. jobject obj=env->NewObject(cls_obj,m);
  70. jobject o1=env->NewStringUTF("AP2");
  71. env->SetObjectField(obj,fid_ssid,o1);
  72. jobject o2=env->NewStringUTF("22-22-22-22-22-22");
  73. env->SetObjectField(obj,fid_mac,o2);
  74. env->SetIntField(obj,fid_level,-66);
  75. env->SetObjectArrayElement(obj_array,i,obj);
  76. }
  77. return obj_array;
  78. }
  79. /*
  80. * Class:     com_ldq_list_WifiManager
  81. * Method:    getScanResults
  82. * Signature: ()Ljava/util/List;
  83. */
  84. JNIEXPORT jobject JNICALL Java_com_ldq_list_WifiManager_getScanResults (JNIEnv *env, jclass cls)
  85. {
  86. jclass m_cls_list    = env->FindClass("java/util/ArrayList");
  87. jmethodID m_mid_list = env->GetMethodID(m_cls_list,"<init>","()V");
  88. jobject m_obj_list   = env->NewObject(m_cls_list,m_mid_list);
  89. jmethodID m_mid_add  = env->GetMethodID(m_cls_list,"add","(Ljava/lang/Object;)Z");
  90. jclass m_cls_result    = env->FindClass("com/ldq/list/ScanResult");
  91. jmethodID m_mid_result = env->GetMethodID(m_cls_result,"<init>","()V");
  92. jobject m_obj_result   = env->NewObject(m_cls_result,m_mid_result);
  93. jfieldID m_fid_1 = env->GetFieldID(m_cls_result,"ssid","Ljava/lang/String;");
  94. jfieldID m_fid_2 = env->GetFieldID(m_cls_result,"mac","Ljava/lang/String;");
  95. jfieldID m_fid_3 = env->GetFieldID(m_cls_result,"level","I");
  96. env->SetObjectField(m_obj_result,m_fid_1,env->NewStringUTF("AP6"));
  97. env->SetObjectField(m_obj_result,m_fid_2,env->NewStringUTF("66-66-66-66-66-66"));
  98. env->SetIntField(m_obj_result,m_fid_3,-66);
  99. env->CallBooleanMethod(m_obj_list,m_mid_add,m_obj_result);
  100. return m_obj_list;
  101. }

【转】JNI 对象处理的更多相关文章

  1. JNI 对象处理 (转)

    JNI 的基本问题就是解决 Java 和 C++ 代码互相调用的通信问题,在 C++ 代码编写过程中最大的问题莫过于适应其中的代码编写规则,C++调用或是返回的内容必须遵守 JVM 和 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. spring 定时任务的 执行时间设置规则

    单纯针对时间的设置规则org.springframework.scheduling.quartz.CronTriggerBean允许你更精确地控制任务的运行时间,只需要设置其cronExpressio ...

  2. 第三篇:python高级之生成器&迭代器

    python高级之生成器&迭代器   python高级之生成器&迭代器 本机内容 概念梳理 容器 可迭代对象 迭代器 for循环内部实现 生成器 1.概念梳理 容器(container ...

  3. HTML5常用标签

    section 板块,用于划分页面的不同区域或者划分文章里不同的节 ↓  header 页面头部或者板块section头部 ↓  footer 页面底部或者section底部 ↓  nav 导航(包含 ...

  4. 表达式:使用API创建表达式树(3)

    一.DebugInfoExpression:发出或清除调试信息的序列点. 这允许调试器在调试时突出显示正确的源代码. static void Main(string[] args) { var asm ...

  5. asp.net对word文档进行修改 对于使用word文档做模板编辑比较适用

    最近做项目,需要多word文档进行编辑并导出一个新的word,在最初的word编辑中留下特定的字符串用来替换,然后在本地生成一个新的word文档,并且不修改服务器中的word文档,这样才能保证服务器中 ...

  6. 实现HTTP跳转到HTTPS

    1 首先在您的网站下新建一个站点,名称随意,在属性中分配TCP端口为80,SSL不分配 然后在属性>主目录下配置 将此资源的内容来自: 改为 重定向到URL 然后重定向到中  输入:  HTTP ...

  7. exp/imp 有很多弊端

    弊端1. 空表 无法执行导出操作弊端2. 高版本的导出文件  无法使用 低版本的 oracle软件 导入 环境准备:create table test0707(n1 date); 认证弊端1 案例1. ...

  8. iOS目录结构

    默认情况下,每个沙盒含有3个文件夹:Documents, Library 和 tmp.因为应用的沙盒机制,应用只能在几个目录下读写文件 Documents:苹果建议将程序中建立的或在程序中浏览到的文件 ...

  9. iOS 里面如何使用第三方应用程序打开自己的文件,调用wps其他应用打开当前应用里面的的ppt doc xls

    我们的自己的应用里面经常涉及的要打开ppt doc,这样的功能,以前总以为iOS沙盒封闭化,不可能实现,后来终于解决了 使用 UIDocumentInteractionController 来解决这一 ...

  10. [转]mysql自动定时备份数据库的最佳方法-支持windows系统

    网上有很多关于window下Mysql自动备份的方法,可是真的能用的也没有几个,有些说的还非常的复杂,难以操作. 我们都知道mssql本身就自带了计划任务可以用来自动备份,可是mysql咱们要怎么样自 ...