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 |
Z |
byte
|
B |
char
|
C |
short |
S |
int |
I |
long |
L |
float |
F |
double
|
D |
void
|
V |
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);
-
返回:
下面是本人练习的例子
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);
}
}
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;
}
}
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();
}
#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;
}
分享到:
相关推荐
JNI处理hashmap,string等对象的操作,别处绝对没有的
在jni中操作arraylist对象,然后添加一个int型数据进去
3、实例三、在jni函数中访问java类中的对象实例域... 58 4、实例四:在jni函数中访问类的静态实例域... 60 5、实例五:在jni函数中调用java对象的方法... 60 6、实例六:在jni函数中调用java类的静态方法... 61 ...
在实现过程中,需要使用jni.pas文件中的类型和结构体来定义JNIEnv和Java对象。 在开发JNI应用时,需要注意命名规则,例如,过程名称需要以Java开头,并使用下划线将Java类的包名、类名和方法名连起来。否则,Java类...
* 异常处理:使用try-catch语句处理JNI调用中的错误。 * 错误代码:使用错误代码来处理JNI调用中的错误。 知识点6:JNI的安全性 JNI提供了多种安全机制,包括: * 认证机制:验证JNI调用者的身份和权限。 * 访问...
本资源演示了基本的jni调用,在资源中有详细的说明,对象访问、方法访问、数组访问、异常处理已经缓存机制。
JNI实例,jni的基本使用,包括回调,传递map集合,处理复杂对象等等的使用
6、 新增一个方法处理java对象 26 7、 新增一个方法处理数组 29 8、 改写RunMain 32 四、 参考资料: 33 V. Eclipse+CDT+MinGW 进行JAVA调用C/C++ 34 一、 安装eclipse3.2。 34 二、 安装MinGW。 34 1、 下载MinGW...
里面包含了C和java之间的调用,简单对象的调用,复杂对象的处理,回调函数,异常处理
2.4.8 JNI中的异常处理 2.5 本章小结 第3章 深入理解init 3.1 概述 3.2 init分析 3.2.1 解析配置文件 3.2.2 解析service 3.2.3 init控制service 3.2.4 属性服务 3.3 本章小结 第4章 深入理解zygote 4.1 概述 4.2 ...
它正在使用Android4OpenCV库的缩减版本通过JNI接口传递帧,以便使用OpenMakaEngine进行处理。 定制分支 该分支实现了自定义的Camera API,以通过AsyncTasks将单个帧传递到JNI接口。 OpenMakaEngine尚未移植。 设置 ...
1、哪些情况下的对象会被垃圾回收机制处理掉? 利用可达性分析算法,虚拟机会将一些对象定义为 GC Roots,从 GC Roots 出发沿着引用链 向下寻找,如果某个对象不能通过 GC Roots 寻找到,虚拟机就认为该对象可以被...
该类的构造函数中会创建一个 Looper 对象,用于处理输入事件。 在 Android 的开机过程中,SystemServer 会启动 Input 服务,Input 服务会启动 WindowManagerService,WindowManagerService 又会启动 InputManager。...
在 `GpsLocationProvider` 类中,有一个 `enable` 函数,该函数会发送一个 enable 消息,并在消息处理对象中处理该消息。`handleEnable` 函数是 `enable` 函数的回调函数,它会执行初始化 GPS 的相关操作。 四、...
同时,会实例化一个消息处理对象 `ProviderHandler`,该对象负责处理来自框架层的消息。 三、消息处理对象和线程交互 在 `ProviderHandler` 中,会处理来自框架层的消息,例如 ENABLE 和 ENABLE_TRACKING 消息。当...
5. 可连接现有 / 原有的系统:RMI 可通过 Java 的本机方法接口 JNI 与现有系统进行交互。 6. 分布式垃圾收集:RMI 采用其分布式垃圾收集功能收集不再被网络中任何客户程序所引用的远程服务对象。 7. 并行计算:RMI ...
Oracle的PreparedStatement类不完全支持BLOB和CLOB等大对象的处理,尤其是Thin驱动程序不支持利用PreparedStatement对象的setObject()和setBinaryStream()方法设置BLOB的值,也不支持利用setCharacterStream()方法...
GC Roots是垃圾回收机制的起点,包括虚拟机栈、方法区中的类静态属性引用的对象、本地方法栈中JNI引用的对象等。对象如果不能通过GC Roots寻找到,将被认为可以被回收。 2. GC Roots GC Roots是垃圾回收机制的起点...
相信有些Android&图像算法开发者和我一样,遇到过这样的状况:要对Bitmap对象做一些密集计算(例如逐像素的滤波),但是在java层写循环代码来逐像素操作明显是不现实的,因为Java代码的运行速度太慢,而一副很小的...
本书全面介绍了Java语言的特点和功能,主要包括Java编程基础知识、Java算术运算符、Java编程语法、面向对象程序设计基本概念、系统类的使用和应用、图形用户界面设计、图形处理、多媒体处理、异常处理、多线程、网络...