`
leidiqiu
  • 浏览: 133003 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

JNI 对象处理

    博客分类:
  • 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 Z 

byte

B 

char

 
short S 
int I 
long  
float  

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);
  • 返回:
    • 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;
}


 

 

分享到:
评论
3 楼 zhangdong92 2016-05-26  
ihopethatwell 写道
楼主,直接return env->NewStringUTF("hello");   不会有内存溢出?

内存溢出?是指内存泄露吗?
我刚才也有这个疑问,参考这个
jni内存泄露 - 饭特稀 - BlogJava
http://www.blogjava.net/neumqp/archive/2006/03/02/33152.html
返回java的env->New...的对象不需要手动释放,其它的都需要,包括在c中env->NewObjectClass生成的没有返回java的对象
2 楼 ihopethatwell 2013-04-03  
楼主,直接return env->NewStringUTF("hello");   不会有内存溢出?
1 楼 kissdarkwind 2011-11-21  
如何释放这个对象呢,仅仅从java端置为null可以吗?还是从jni这里也要释放?jni这边new出来的是一个local reference呢还是一个global reference? 亦或是一个weak reference?

相关推荐

    JNI处理hashmap,string等对象的操作

    JNI处理hashmap,string等对象的操作,别处绝对没有的

    jni操作arraylist对象

    在jni中操作arraylist对象,然后添加一个int型数据进去

    JNI完全技术手册 带完整书签

    3、实例三、在jni函数中访问java类中的对象实例域... 58 4、实例四:在jni函数中访问类的静态实例域... 60 5、实例五:在jni函数中调用java对象的方法... 60 6、实例六:在jni函数中调用java类的静态方法... 61 ...

    Android JNI基本示例

    本资源演示了基本的jni调用,在资源中有详细的说明,对象访问、方法访问、数组访问、异常处理已经缓存机制。

    JNI实例的使用

    JNI实例,jni的基本使用,包括回调,传递map集合,处理复杂对象等等的使用

    JNI技术手册 c/c++调用java

    6、 新增一个方法处理java对象 26 7、 新增一个方法处理数组 29 8、 改写RunMain 32 四、 参考资料: 33 V. Eclipse+CDT+MinGW 进行JAVA调用C/C++ 34 一、 安装eclipse3.2。 34 二、 安装MinGW。 34 1、 下载MinGW...

    JNIAndroid

    里面包含了C和java之间的调用,简单对象的调用,复杂对象的处理,回调函数,异常处理

    《深入理解Android》卷Ⅰ

    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 ...

    OpenMakaAndroid:OpenMakaAndroid-具有JNI支持的Android设备的无标记对象检测

    它正在使用Android4OpenCV库的缩减版本通过JNI接口传递帧,以便使用OpenMakaEngine进行处理。 定制分支 该分支实现了自定义的Camera API,以通过AsyncTasks将单个帧传递到JNI接口。 OpenMakaEngine尚未移植。 设置 ...

    大厂真题之京东-Java实习生

    1、哪些情况下的对象会被垃圾回收机制处理掉? 利用可达性分析算法,虚拟机会将一些对象定义为 GC Roots,从 GC Roots 出发沿着引用链 向下寻找,如果某个对象不能通过 GC Roots 寻找到,虚拟机就认为该对象可以被...

    jdbc连接数据库的方式2

     Oracle的PreparedStatement类不完全支持BLOB和CLOB等大对象的处理,尤其是Thin驱动程序不支持利用PreparedStatement对象的setObject()和setBinaryStream()方法设置BLOB的值,也不支持利用setCharacterStream()方法...

    Android中利用C++处理Bitmap对象的实现方法

    相信有些Android&图像算法开发者和我一样,遇到过这样的状况:要对Bitmap对象做一些密集计算(例如逐像素的滤波),但是在java层写循环代码来逐像素操作明显是不现实的,因为Java代码的运行速度太慢,而一副很小的...

    vc++6.0 程序设计学与用教程

    本书全面介绍了Java语言的特点和功能,主要包括Java编程基础知识、Java算术运算符、Java编程语法、面向对象程序设计基本概念、系统类的使用和应用、图形用户界面设计、图形处理、多媒体处理、异常处理、多线程、网络...

    Oracle Olap开发备忘录

    1、很早以前就针对Oracle 8里面的Express Server作了开发,当时是使用dml的C接口,在Java &lt;br&gt;里面通过JNI访问,虽然只有一个命令接口,但是着实费力,同时JNI对J2EE Application &lt;br&gt;Server也有所影响。...

    《Android系统源代码情景分析》

    2.4.3 实现硬件访问服务的JNI方法 2.4.4 启动硬件访问服务 2.5 开发Android应用程序来使用硬件访问服务 第3章 智能指针 3.1 轻量级指针 3.1.1 实现原理分析 3.1.2 应用实例分析 3.2 强指针和弱指针 ...

    Android系统源代码情景分析-罗升阳-源码

    2.4.3 实现硬件访问服务的JNI方法 2.4.4 启动硬件访问服务 2.5 开发Android应用程序来使用硬件访问服务 第3章 智能指针 3.1 轻量级指针 3.1.1 实现原理分析 3.1.2 应用实例分析 3.2 强指针和弱指针 3.2.1 ...

    Thinking in Java 中文第四版+习题答案

    A.1.5 JNI和线程处理 A.1.6 使用现成代码 A.2 微软的解决方案 A.3.1 @dll.import引导命令 A.3.2 com.ms.win32包 A.3.3 汇集 A.3.4 编写回调函数 A.3.5 其他J/Direct特性 A.4 本原接口(RNI) A.4.1 RNI总结 A.5 Java...

    Think in Java(中文版)chm格式

    A.1.5 JNI和线程处理 A.1.6 使用现成代码 A.2 微软的解决方案 A.3 J/Direct A.3.1 @dll.import引导命令 A.3.2 com.ms.win32包 A.3.3 汇集 A.3.4 编写回调函数 A.3.5 其他J/Direct特性 A.4 本原接口(RNI) ...

    Java初学者入门教学

    A.1.5 JNI和线程处理 A.1.6 使用现成代码 A.2 微软的解决方案 A.3 J/Direct A.3.1 @dll.import引导命令 A.3.2 com.ms.win32包 A.3.3 汇集 A.3.4 编写回调函数 A.3.5 其他J/Direct特性 A.4 本原接口(RNI) A.4.1 RNI...

    JAVA_Thinking in Java

    A.1.5 JNI和线程处理 A.1.6 使用现成代码 A.2 微软的解决方案 A.3 J/Direct A.3.1 @dll.import引导命令 A.3.2 com.ms.win32包 A.3.3 汇集 A.3.4 编写回调函数 A.3.5 其他J/Direct特性 A.4 本原接口(RNI) A.4.1 RNI...

Global site tag (gtag.js) - Google Analytics