`
hm4123660
  • 浏览: 278763 次
  • 性别: Icon_minigender_1
  • 来自: 广州
博客专栏
Dea4ce76-f328-3ab2-b24a-fb268e1eeb75
数据结构
浏览量:69148
社区版块
存档分类
最新评论

jni操作java属性和方法

    博客分类:
  • JNI
阅读更多

              之前实现了简单的jni入门实例, 这篇博客将主要介绍使用jni在c++调用java的属性和方法。

 

本地方法函数有两个参数,JNIEnv *和jobject,这两个参数非常重要



 

1.JNI数据类型

为了方便记忆和书写java数据类型与c++数据类型的对应,jni对数据进行封装。具体为下



 

2.获取java属性和方法

 

   首先需要获取对应的java的类,jni专门定义了jclass类型来表示java的Class类,JNIEvn类中有几个函数取得jclass:

      1.jclass FindClass(const char * clsName)----传入完整类名

      2.jclass GetObjectClass(jobject obj)------传入类示例

      3.jclass GetSuperClass(jclass obj)-------传入Class类

 

如: jclass string_class=evn->FindClass("java/lang/String")获取String类

     得到java类后,访问java的属性或方法首先还要在本地代码中获取java属性的jfieldID和java方法的jmethodID才能进行使用。

    使用JNIEvn的

                  1.GetFieldID/GetMethodID来获取非静态的属性和方法

                  2.GetStaticFieldID/GetStaticMethodID来获取静态的属性和方法

 

获取属性参数:(类,属性名,属性签名)

 

获取方法参数:(类,方法名,方法签名)

 

我们都知道java能对方法进行重载,为了准确获取对应的方法和属性,jni引入了Sign(签名),具体如下:




 

获取到java属性的ID后,就可获取和修改java的属性了,非静态属性可调用

Set/GetIntFieldSet/GetBooleanFieldSet/GetDoubleField

Set/GetFloatField

Set/GetLongField

Set/GetShortField

Set/GetObjectField-----------对应数组等

静态属性可调用

Set/GetStaticIntFieldSet/GetStaticBooleanFieldSet/GetStaticDoubleField

Set/GetStaticFloatField

Set/GetStaticLongField

Set/GetStaticShortField

Set/GetStaticObjectField

 

下面举实例

1.调用java属性

java代码如下,在本地方法sayhello里修改其属性score

package com.example;


public class jni_test {

	//在本地方法sayHello里修改score的值
	public native void sayHello();
	
	public float score=99.9f;
	
	static{
		System.loadLibrary("NativeCode");
	}
	
    public static void main(String[] args) {
    	
    	jni_test temp=new jni_test();
    	
    	temp.sayHello();
    	//输出temp的score属性的值
    	System.out.println("score: "+temp.score);
		
	}
}

 

c++本地方法实现的代码:

#include"com_example_jni_test.h"
#include<iostream>
using namespace std;

JNIEXPORT void JNICALL Java_com_example_jni_1test_sayHello(JNIEnv * evn, jobject obj)
{
	//获取java的Class--sayHello方法是非静态方法,所以此时obj是调用这个函数的实例,即java中的实例temp
	jclass my_class=evn->GetObjectClass(obj);
	//jclass my_class=evn->FindClass("com/example/jni_test");也可以获取Class
	//获取java的score属性的FieldID
	jfieldID score_id=evn->GetFieldID(my_class,"score","F");//(类,属性名.签名)
	//根据FieldID获取属性
	jfloat score=evn->GetFloatField(obj,score_id);//(实例对象,属性ID)
	//修改java的temp的score的值
	evn->SetFloatField(obj,score_id,88.8);

}

 编译生成dll加入PATH即可.

 

运行结果为:



 

至此,成功获取java对象的属性并修改其属性的值

 

2.调用java方法

在本地方法里调用Max_num,输出最大值

java代码:

package com.example;


public class jni_test {

	//在本地方法sayHello里调用Max_num方法
	public native void sayHello();
	
	//返回最大值
	public void Max_num(int ok,int ok1)
	{
		if(ok>ok1)
			System.out.println("最大值是: "+ok);
		else 
			System.out.println("最大值是: "+ok1);
	}
	
	static{
		System.loadLibrary("NativeCode");
	}
	
    public static void main(String[] args) {
    	
    	jni_test temp=new jni_test();
    	
    	temp.sayHello();//输出最大值	
	}
}

 

 

本地方法C++实现

#include"com_example_jni_test.h"
#include<iostream>
using namespace std;

JNIEXPORT void JNICALL Java_com_example_jni_1test_sayHello(JNIEnv * evn, jobject obj)
{
	//获取java的Class--sayHello方法是非静态方法,所以此时obj是调用这个函数的实例,即java中的实例temp
	jclass my_class=evn->GetObjectClass(obj);
	//jclass my_class=evn->FindClass("com/example/jni_test");也可以获取Class
	//获取java的Max_num方法的ID
	jmethodID max_id=evn->GetMethodID(my_class,"Max_num","(II)V");//(类,属性名.签名)	
	//调用Max_num方法--Call<type>Method--type函数返回值
	evn->CallVoidMethod(obj,max_id,100,123);//(对象,方法ID,参数...)


}

 

运行结果:



 

 

3
1
分享到:
评论

相关推荐

    jni基本操作

    1)传递基础数据类型 2)传递返回字符串类型 3)传递返回数组 4)Native层操作java类属性 5)Native层回调java方法 6)传递返回一个java类 7)Native线程回调java方法 8)Native调用第三方库

    JAVA上百实例源码以及开源项目

    6个目标文件,EJB来模拟银行ATM机的流程及操作:获取系统属性,初始化JNDI,取得Home对象的引用,创建EJB对象,并将当前的计数器初始化,调用每一个EJB对象的count()方法,保证Bean正常被激活和钝化,EJB对象是用...

    java 编程入门思考

    10.2 增添属性和有用的接口 10.2.1 通过FilterInputStream从InputStream里读入数据 10.2.2 通过FilterOutputStream向OutputStream里写入数据 10.3 本身的缺陷:RandomAccessFile 10.4 File类 10.4.1 目录列表器 ...

    JAVA上百实例源码以及开源项目源代码

    6个目标文件,EJB来模拟银行ATM机的流程及操作:获取系统属性,初始化JNDI,取得Home对象的引用,创建EJB对象,并将当前的计数器初始化,调用每一个EJB对象的count()方法,保证Bean正常被激活和钝化,EJB对象是用...

    Java初学者入门教学

    10.2 增添属性和有用的接口 10.2.1 通过FilterInputStream从InputStream里读入数据 10.2.2 通过FilterOutputStream向OutputStream里写入数据 10.3 本身的缺陷:RandomAccessFile 10.4 File类 10.4.1 目录列表器 ...

    java联想(中文)

    10.2 增添属性和有用的接口 10.2.1 通过FilterInputStream从InputStream里读入数据 10.2.2 通过FilterOutputStream向OutputStream里写入数据 10.3 本身的缺陷:RandomAccessFile 10.4 File类 10.4.1 目录列表器 ...

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

    10.2 增添属性和有用的接口 10.2.1 通过FilterInputStream从InputStream里读入数据 10.2.2 通过FilterOutputStream向OutputStream里写入数据 10.3 本身的缺陷: 10.4 File类 10.4.1 目录列表器 10.4.2 检查与创建...

    JAVA_Thinking in Java

    10.2 增添属性和有用的接口 10.2.1 通过FilterInputStream从InputStream里读入数据 10.2.2 通过FilterOutputStream向OutputStream里写入数据 10.3 本身的缺陷:RandomAccessFile 10.4 File类 10.4.1 目录列表器 ...

    Thinking in Java简体中文(全)

    10.2 增添属性和有用的接口 10.2.1 通过FilterInputStream从InputStream里读入数据 10.2.2 通过FilterOutputStream向OutputStream里写入数据 10.3 本身的缺陷:RandomAccessFile 10.4 File类 10.4.1 目录列表器 ...

    robusta:在Rust和Java之间轻松互操作

    robusta — Rust和Java之间的轻松互操作 该库提供了一个过程宏,可以更轻松地在Rust中编写与JNI兼容的代码。 它可以执行Rust-y输入和输出类型的自动转换(请参阅)。 [ dependencies ] robusta_jni = " 0.1 " 用法...

    JAVA_Thinking in Java(中文版 由yyc,spirit整理).chm

    10.2 增添属性和有用的接口 10.2.1 通过FilterInputStream从InputStream里读入数据 10.2.2 通过FilterOutputStream向OutputStream里写入数据 10.3 本身的缺陷:RandomAccessFile 10.4 File类 10.4.1 目录列表器 ...

    Think in Java(中文版)chm格式

    10.2 增添属性和有用的接口 10.2.1 通过FilterInputStream从InputStream里读入数据 10.2.2 通过FilterOutputStream向OutputStream里写入数据 10.3 本身的缺陷:RandomAccessFile 10.4 File类 10.4.1 目录列表器...

    jni-loader:基于运行时平台动态加载捆绑的JNI库

    它根据系统属性os.name和os.arch的值规范化操作系统和体系结构,然后在类路径上查找 zip 存档${libName}-${os}-${arch}并提取其内容到一个临时目录。 临时目录和存档中找到的任何子目录都被添加到java.library.path...

    《深入理解Android》卷Ⅰ

    2.3.2 Java的native函数和总结 2.4 JNI层MediaScanner的分析 2.4.1 注册JNI函数 2.4.2 数据类型转换 2.4.3 JNIEnv介绍 2.4.4 通过JNIEnv操作jobject 2.4.5 jstring介绍 2.4.6 JNI类型签名介绍 2.4.7 垃圾回收 2.4.8 ...

    Thinking in Java(中文版 由yyc,spirit整理).chm

    10.2 增添属性和有用的接口 10.2.1 通过FilterInputStream从InputStream里读入数据 10.2.2 通过FilterOutputStream向OutputStream里写入数据 10.3 本身的缺陷:RandomAccessFile 10.4 File类 10.4.1 目录列表器 ...

    Java WEB 电子杂志

    但是其中还是有一些问题,如CMYK图片的操作,可喜的是这种图片非常之少,涉及到了很多的图形编程,Java在这一块不是太强(特别是JDK1.4,图形处理有很多BUG),能使用JNI接口来调用其他语言处理图形是最好不过了。

    JNA 3.3.0 API

    如果文件打开看不到右边的内容,是因为你的操作系统为了安全对下载的chm文件进行了锁定,只需要在打开前右键单击该chm文件选择“属性”,然后在“常规”选项卡的下方单击“解除锁定”按钮就可以了。如果还是不能看,...

    ThinkInJava

    10.2 增添属性和有用的接口 10.2.1 通过FilterInputStream从InputStream里读入数据 10.2.2 通过FilterOutputStream向OutputStream里写入数据 10.3 本身的缺陷:RandomAccessFile 10.4 File类 10.4.1 目录列表器 ...

    thinkinjava

    10.2 增添属性和有用的接口 10.2.1 通过FilterInputStream从InputStream里读入数据 10.2.2 通过FilterOutputStream向OutputStream里写入数据 10.3 本身的缺陷:RandomAccessFile 10.4 File类 10.4.1 目录列表器 ...

Global site tag (gtag.js) - Google Analytics