您的位置:首页 > 编程语言 > Java开发

JNI学习笔记(三)JNI中本地语言访问Java类中的属性与方法(附例子)

2012-08-01 14:34 441 查看
        接着上一篇的学习( JNI学习笔记(二)JNI中的java语言与本地C/C++语言之间的映射)

      今天学习JNI中本地语言访问Java类中的属性与方法:

      

      首先要访问Java类中的属性与方法,我们要先去了解一下属性与方法的签名:因为在使用本地方法访问的时候需要使用到这些签名;

       


   

       以后要使用到各种签名可以上表查询,不过jdk中有个命令工具javap,可以轻松的为我们显示出java中的各种属性与方法的签名,

  

       下面我们来看下使用的方法;

        


       

        一般使用的时候,直接来个javap -s -p 完整类名,加上-p,可以属性所有的属性与方法的签名,下面看下我的例子中的生成:

    

       


       看,用这个javap工具很容易生成,到时候我们在本地方法中需要的时候,直接把签名照着写进去进行,还能提供正确哈。

        好了,了解了签名,下面可以进入正题了   

 

 (一):本地方法访问Java类中的属性

    java例子代码如下:

package com.jiangqq.jni;
/**
* 本地方法访问Java类的属性与方法例子
* @author jiangqq
* <a href http://blog.csdn.net/jiangqq781931404>CSDN 记录自己的成长历程</a>
*/
public class TestJni {
private int sum=10;
double add(double a,double b)
{
return a+b;
}
public native void invoked();
public static void main(String[] args) {
System.loadLibrary("nativeCode4");
TestJni testJni=new TestJni();
testJni.invoked();
}

}


    要从本地方法中去访问到Java类,我们可以再JNI.h文件发现三个主要获取jclass的方法,因为在jni中已经定义了jclass类型来标识Java的class类了

     jclass FindClass(const char *name) {

        return functions->FindClass(this, name);

    }
     jclass GetObjectClass(jobject obj) {

        return functions->GetObjectClass(this,obj);

    }

    jclass GetSuperclass(jclass sub) {

        return functions->GetSuperclass(this, sub);

    }
       上面的三个方法,我们都可以再jni.h头文件中找到,现在开始使用本地方法访问java中的属性并且修改;
我的例子中
       步骤:

获取jclass,(上面的例子的native方法时非静态的,所以传入到本地方法是实例对象,可以使用第二种获取jclass的方法)
获取jfieldID,(jfieldID GetFieldID(jclass clazz, const char *name, const char *sig) {return functions>GetFieldID(this,clazz,name,sig); })
设置该属性的新值 使用 Set<Type>Field,Type代码该属性的类型,
    上面的那些方法(尤其第三个,我们都可以再jni.h头文件中找到相对应的),如果要访问静态的属性也是类似的,大家可以尝试一下的;

     
      访问Java属性与修改属性的本地代码如下:   
#include"com_jiangqq_jni_TestJni.h"
#include<stdio.h>
JNIEXPORT void JNICALL Java_com_jiangqq_jni_TestJni_invoked
(JNIEnv * env, jobject obj)
{
//////////本地代码调用修改Java属性///////////////
jclass j_class= env->GetObjectClass(obj);
jfieldID j_sum= env->GetFieldID(j_class,"sum","I");
env->SetIntField(j_class,j_sum,20);
jint j_sum2=env->GetIntField(j_class,j_sum);
printf("%d\n",j_sum2);

}
      
 (二)本地方法访问Java的方法:
     步骤:

    和上面的相似,首先获取jclass,(参照本地语言访问java属性的第一步)
    获取jmethodID, jmethodID (JNICALL *GetMethodID) (JNIEnv *env, jclass clazz, const char *name, const char *sig);
     调用Call<Type>Method,介绍一个比较常用的方法:我们可以使用Call<Type>Method(JNIEnv *env, jobject obj, jmethodID methodID, ...)
    [注]如果要调用的方法时一个静态方法,那么就可以使用CallStatic<Type>Method(...),当然这些方法也可以在jni.h头文件中找到.

     
     调用Java语言中的方法的本地代码如下:
#include"com_jiangqq_jni_TestJni.h"
#include<stdio.h>
JNIEXPORT void JNICALL Java_com_jiangqq_jni_TestJni_invoked
(JNIEnv * env, jobject obj)
{
///////////本地代码调用Java方法/////////////////
jclass j_class= env->GetObjectClass(obj);
jmethodID j_add= env->GetMethodID(j_class,"add","(DD)D");
jdouble j_add_sum= env->CallDoubleMethod(obj,j_add,1.1,3.2);
printf("%.2f\n",j_add_sum);
}
     
  例子代码下载链接:http://download.csdn.net/detail/jiangqq781931404/4468825
        

   
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐