Android JNI入门第四篇——jni头文件分析

转载请标明出处:
http://blog.csdn.net/michael1112/article/details/56666407

江东橘子的博客


一、 首先写了java文件:

public class HeaderFile {
    private   native void doVoid();
    native int doShort();
    native void doArray(Object[] o);
    native int doInt(int i);      //byte ,short ,int,long,float,double ,boolean,char
    native int doInt(double d);   //byte ,short ,int,long,float,double ,boolean,char
    native int doInt(Objects o);
    native int doInt(double d1,double d2);
    static  native  int doInt(double d1,double d2,double d3);
    static  native  int doInt(double d1,float f,boolean b,char[] c);

    native int doInt(int[] i);
    native int doInt(int[] i1,double[] i2);
    static native int doInt(int[] i1,double[] i2,Object[] o);

    public native String doString(String s);
    public native Object doObject(Object o);
    public native Enumeration[] doInterface(Iterator[] it);
    public native Student[] doSdudent(Student[] s);

    public native static Object doAll(int[] i , String[] s , Student[] student );

}

  Java文件中包含了private、public、protect等类型的方法,static 方法和非static 方法,返回类型有基础类型、对象等。


HeaderFile中用到的Student 类我们新建一个Student类

public class Student {
    private  String name;
    private String sex;
}


二、下面看一下生成的头文件:

/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class com_jdjz_myapplication_HeaderFile */

#ifndef _Included_com_jdjz_myapplication_HeaderFile
#define _Included_com_jdjz_myapplication_HeaderFile
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     com_jdjz_myapplication_HeaderFile
 * Method:    doVoid
 * Signature: ()V
 */
JNIEXPORT void JNICALL Java_com_jdjz_myapplication_HeaderFile_doVoid
  (JNIEnv *, jobject);

/*
 * Class:     com_jdjz_myapplication_HeaderFile
 * Method:    doShort
 * Signature: ()I
 */
JNIEXPORT jint JNICALL Java_com_jdjz_myapplication_HeaderFile_doShort
  (JNIEnv *, jobject);

/*
 * Class:     com_jdjz_myapplication_HeaderFile
 * Method:    doArray
 * Signature: ([Ljava/lang/Object;)V
 */
JNIEXPORT void JNICALL Java_com_jdjz_myapplication_HeaderFile_doArray
  (JNIEnv *, jobject, jobjectArray);

/*
 * Class:     com_jdjz_myapplication_HeaderFile
 * Method:    doInt
 * Signature: (I)I
 */
JNIEXPORT jint JNICALL Java_com_jdjz_myapplication_HeaderFile_doInt__I
  (JNIEnv *, jobject, jint);

/*
 * Class:     com_jdjz_myapplication_HeaderFile
 * Method:    doInt
 * Signature: (D)I
 */
JNIEXPORT jint JNICALL Java_com_jdjz_myapplication_HeaderFile_doInt__D
  (JNIEnv *, jobject, jdouble);

/*
 * Class:     com_jdjz_myapplication_HeaderFile
 * Method:    doInt
 * Signature: (Ljava/util/Objects;)I
 */
JNIEXPORT jint JNICALL Java_com_jdjz_myapplication_HeaderFile_doInt__Ljava_util_Objects_2
  (JNIEnv *, jobject, jobject);

/*
 * Class:     com_jdjz_myapplication_HeaderFile
 * Method:    doInt
 * Signature: (DD)I
 */
JNIEXPORT jint JNICALL Java_com_jdjz_myapplication_HeaderFile_doInt__DD
  (JNIEnv *, jobject, jdouble, jdouble);

/*
 * Class:     com_jdjz_myapplication_HeaderFile
 * Method:    doInt
 * Signature: (DDD)I
 */
JNIEXPORT jint JNICALL Java_com_jdjz_myapplication_HeaderFile_doInt__DDD
  (JNIEnv *, jclass, jdouble, jdouble, jdouble);

/*
 * Class:     com_jdjz_myapplication_HeaderFile
 * Method:    doInt
 * Signature: (DFZ[C)I
 */
JNIEXPORT jint JNICALL Java_com_jdjz_myapplication_HeaderFile_doInt__DFZ_3C
  (JNIEnv *, jclass, jdouble, jfloat, jboolean, jcharArray);

/*
 * Class:     com_jdjz_myapplication_HeaderFile
 * Method:    doInt
 * Signature: ([I)I
 */
JNIEXPORT jint JNICALL Java_com_jdjz_myapplication_HeaderFile_doInt___3I
  (JNIEnv *, jobject, jintArray);

/*
 * Class:     com_jdjz_myapplication_HeaderFile
 * Method:    doInt
 * Signature: ([I[D)I
 */
JNIEXPORT jint JNICALL Java_com_jdjz_myapplication_HeaderFile_doInt___3I_3D
  (JNIEnv *, jobject, jintArray, jdoubleArray);

/*
 * Class:     com_jdjz_myapplication_HeaderFile
 * Method:    doInt
 * Signature: ([I[D[Ljava/lang/Object;)I
 */
JNIEXPORT jint JNICALL Java_com_jdjz_myapplication_HeaderFile_doInt___3I_3D_3Ljava_lang_Object_2
  (JNIEnv *, jclass, jintArray, jdoubleArray, jobjectArray);

/*
 * Class:     com_jdjz_myapplication_HeaderFile
 * Method:    doString
 * Signature: (Ljava/lang/String;)Ljava/lang/String;
 */
JNIEXPORT jstring JNICALL Java_com_jdjz_myapplication_HeaderFile_doString
  (JNIEnv *, jobject, jstring);

/*
 * Class:     com_jdjz_myapplication_HeaderFile
 * Method:    doObject
 * Signature: (Ljava/lang/Object;)Ljava/lang/Object;
 */
JNIEXPORT jobject JNICALL Java_com_jdjz_myapplication_HeaderFile_doObject
  (JNIEnv *, jobject, jobject);

/*
 * Class:     com_jdjz_myapplication_HeaderFile
 * Method:    doInterface
 * Signature: ([Ljava/util/Iterator;)[Ljava/util/Enumeration;
 */
JNIEXPORT jobjectArray JNICALL Java_com_jdjz_myapplication_HeaderFile_doInterface
  (JNIEnv *, jobject, jobjectArray);

/*
 * Class:     com_jdjz_myapplication_HeaderFile
 * Method:    doSdudent
 * Signature: ([Lcom/jdjz/myapplication/Student;)[Lcom/jdjz/myapplication/Student;
 */
JNIEXPORT jobjectArray JNICALL Java_com_jdjz_myapplication_HeaderFile_doSdudent
  (JNIEnv *, jobject, jobjectArray);

/*
 * Class:     com_jdjz_myapplication_HeaderFile
 * Method:    doAll
 * Signature: ([I[Ljava/lang/String;[Lcom/jdjz/myapplication/Student;)Ljava/lang/Object;
 */
JNIEXPORT jobject JNICALL Java_com_jdjz_myapplication_HeaderFile_doAll
  (JNIEnv *, jclass, jintArray, jobjectArray, jobjectArray);

#ifdef __cplusplus
}
#endif
#endif
 


    三、头文件分析如下:

                       1、文件的前九行就不用说了,他们是CC++的头,应该很好理解。

     2、方法的注释部分,每个方法都有它的注释部分,这些都是相似的,对其中一个分析:

/*
 * Class:     com_jdjz_myapplication_HeaderFile
 * Method:    doVoid
 * Signature: ()V
 */

注释部分分为三部分Class、Method、Signature。

Class:表示Native方法的类名称

Method:表示方法名称

Signature:是方法的标识,它是一个标识符,主要供我们在JNI操作java对象的方法使用的。

Signature一般是两部分构成,一个方法的参数,另一个是返回类型。方法参数在括号里面,返回类型在后面,

例如


如果不清楚其中的字符含义,就不能知道其中的意思,其中字符对应有基本类型、对象类型、数组类型。分析如下1)基本类型的对应关系如下



2) 方法参数或者返回值为java中的对象时,必须以“L”加上其路径,不过此路径必须以“/”分开,自定义的对象也使用本规则,不在包中时直接“L”加上类名称。比如说java.lang.String为“java/lang/String”,com.nedu.jni.helloword.Student为"com/nedu/jni/helloword/Student"

3)方法参数或者返回值为数组时类型前加上[,例如[I表示int[],[[[D表示 double[][][],即几维数组就加几个[。

看一下例子:



3、方法的声明

/*
 * Class:     com_jdjz_myapplication_HeaderFile
 * Method:    doArray
 * Signature: ([Ljava/lang/Object;)V
 */
JNIEXPORT void JNICALL Java_com_jdjz_myapplication_HeaderFile_doArray
  (JNIEnv *, jobject, jobjectArray);
   从上面的头文件可以看出方法基本有7部分组成。



1、3部分是都是JNI的关键字,表示此函数是要被JNI调用的。

2、表示方法的返回类型

4、JNI中标识此方法来源于java的标识头

5、方法所在类的包名+类名

6、方法名

7、参数,它们有一个共同的特点,包含JNIEnv *――它是一个接口指针,用于定位函数表中的函数!

     在JNI规范中一般称  为   “Interface Pointer”。看到这儿好像和过程调用很类似了!是的,JNI

     的操作过程,就是面向过程的!后面的jobject是  一个指向该类的指针,类似与C语言中的this。这个

     第二个参数是变化的,当该方法为类的实例方法时该参数为jobject;当该方法为类方法(即静态方法)

     时该参数为jclass,指向该类的class

根据不同方法前缀生成的头文件比较如下:

1、static与非static的比较:


/*
 * Class:     com_jdjz_myapplication_HeaderFile
 * Method:    doInt
 * Signature: (DD)I
 */
JNIEXPORT jint JNICALL Java_com_jdjz_myapplication_HeaderFile_doInt__DD
  (JNIEnv *, jobject, jdouble, jdouble);

/*
 * Class:     com_jdjz_myapplication_HeaderFile
 * Method:    doInt
 * Signature: (DDD)I
 */
JNIEXPORT jint JNICALL Java_com_jdjz_myapplication_HeaderFile_doInt__DDD
  (JNIEnv *, jclass, jdouble, jdouble, jdouble);

第一个是非static方法,第二个是static方法,不同点如上红色标记。其中的不同将在以后提到。

2、privatefriendlyprotected以及public这些方法限制符不会在JNI的头文件中出现。这些访问修饰符只有在其它类

       使用这些方法时有效!JNI中不关心此修饰符!


/**
* @author 江东橘子
* 邮箱:whtchl@126.com
*/


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值