JNI-Native代码访问Java代码(一)

上一篇文章给大家介绍了怎样使用JNI来调用Native代码,在被调用的C/C++函数中也可以反过来访问Java程序中的类,接下来给大家讲解怎样使用Native代码访问Java代码。

.h头文件分析

在上一篇文章中我们使用javah 命令生成的头文件(.h)中有两个非常重要的参数,具体代码如下:

JNIEXPORT void JNICALL Java_com_jony_nativetest_TestNative_sayHello(JNIEnv *, jobject);

参数说明:

JNIEnv类型实际上代表了Java环境。通过这个JNIEnv*指针就可以对Java端的代码进行操作。例如,创建Java类的对象,调用Java对象的方法,获取Java对象的属性等等。

JNIEnv的指针会被JNI传入到本地方法(Native代码)的实现函数中来对Java端的代码进行操作。

JNIEnv类中有很多函数可以使用:

NewObject/NewString/New<TYPE>Array

Get/Set<TYPE>Field

Get/SetStatic<TYPE>Field

Call<TYPE>Method/CallStatic<TYOE>Method等许多函数;

jobject类型指向java对象的引用;该参数使用有两种情况:非静态方法调用(实例:publicnativevoid sayHello();)>> 与该方法相关联的引用——实例对象;

静态方法调用(实例:public native static void sayHello();)>> 代表指向调用类的对象(ClassName.class)。

Java类型在C/C++中对应映射关系如图所示:

获取jclass对象

为了能够在C/C++中使用Java类。JNI.h头文件中专门定义了jclass类型来表示Java中的Class类。

在JNIEnv类中有如下几个简单的函数可以获取jclass:

jclass FindClass(const char* clsName);

jclass GetObjectClass(jobject obj);

jclass GetSuperClass(jclass obj);

实例:

//FindClass会在classpath系统环境变量下寻找类。传入完整类名,注意包与包之间用'/'而不是'.'来分隔。

jclass cls_string = env->FindClass("java/lang/String");//类完整路径名
访问Java类中的属性和方法

在C/C++本地代码中访问Java端的代码,常见的应用就是获取类的属性和调用类的方法。为了在C/C++中表示属性和方法,JNI在jni.h头文件中定义了jfieldID,jmethodID类型来分别代表Java端的属性和方法。
我们在访问或是设置Java属性的时候,首先就要现在本地代码(Native Code)取得代表该Java属性的jfieldID,然后才能在本地代码(Native Code)进行Java属性操作。同样,当我们需要调用Java端的方法时,也是需要取得代表该方法的jmethodID才能进行Java方法调用。

API方法:

使用JNIEnv的   GetFieldID/GetMethodID  或 GetStaticFieldID/GetStaticMethodID来获相应的jfieldID和jmethodID
具体参数及实例如图所示:

从上图中大家可以看到每个方法都有三个参数:

第一个参数是jclass类型,我们可以通过上面所述的方式获得jclass对象;

第二个参数是属性名或方法名;

第三个参数是sign(签名)——用于指定取得属性或方法的类型。

接下来重点讲解一个sign参数的生成方式:

类型对应签名信息如图所示:

sign签名图解:

到此为止大家了解了签名的生成规则,但是非常复杂难以记忆,因此java提供了javap工具来查看类签名信息。

javap命令查看类签名信息

javap命令的使用方式如图所示:

使用javap命令来生成签名

JDK提供了一个工具javap来查看一个类的声明。其中就可以设置输出每个方法/属性的签名。

使用方法:

javap -s -p [full Class Name]

-s 表示输出签名信息

-p 同-private,输出包括private访问权限的成员信息

实例代码(TestNative.java):

package com.jony.nativetest;

import java.util.Date;

public class TestNative {
    public int property;

    public native void sayHello();

    public int function(int i,Date date,int[] arr){
        System.out.println("function");
        return 0;
    }

    /**
     * @param args
     */
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        System.loadLibrary("NativeCode01");// 加载动态链接库
        TestNative testNative = new TestNative();
        testNative.sayHello();
    }
}

编译该java文件后,进入工程目录下的bin目录,执行以下命令:

javap -s -p com.jony.nativetest.TestNative 后运行结果如图所示:

至此,怎么获得签名信息已经完成,谢谢大家的支持!
下一篇文章将给大家介绍本地代码怎样操作Java属性……

 

 

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值