我们知道,使用javah产生c/c++当在头文件,将java定义 native 功能,以产生相应jni层功能,如下面:

/*
* Class: com_lms_jni_JniTest
* Method: getTestString
* Signature: ()Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_com_lms_jni_JniTest_getTestString
(JNIEnv *, jobject);

我们能够看到方法名是以Java_com_lms_jni等开头的。还有什么所谓的Signature。那这些事实上都是什么意思呢。今天我们就来简单地认识一下。

JNI 命名规则

对于传统的JNI编程来说,JNI方法跟Java类方法的名称之间有一定的相应关系。要遵循一定的命名规则,例如以下:

1) 前缀: Java_

2) 类的全限定名。用下划线进行分隔(_):com_lms_jni_JniTest

3) 方法名:getTestString                                             

3) jni函数指定第一个參数:  JNIEnv *

4) jni函数指定第二个參数:  jobject

5) 实际Java參数:               jstring, jint ....

6) 返回值的參数 :                 jstring, jint.... 
所以对于在Java类 com.lms.jni.HwDemo中的一个方法:
public native String addTail(String tail);

其相应的jni层的方法例如以下:

jstring Java_com_lms_jni_HwDemo_addTail(JNIEnv * e, jobject clazz, jstring tail);

假设不这样命名,当把动态库载入进DVM的时候,通过JNIEnv *指针去查找Java Native方法相应的JNI方法的时候。就会找不到了。

注意,我们也能够利用函数注冊的方法,将Java层的方法名跟JNI层的方法名的相应关系保存起来。注冊到DVM中,就不须要这种命名规范了。


JNI 数据类型

我们知道Java的数据类型是跟C/C++的数据类型是不一样的,而JNI是处于Java和Native本地库(大部分是用C/C++写的)中间的一层,JNI对于两种不同的数据类型之间必须做一种转换,所以在JNI跟Java之间就会有数据类型的相应关系。

在JNI中。提供了下面各种数据类型,能够分为原生类型和引用类型:
对于原生类型有:jchar, jbyte, jshort, jint, jlong, jfloat, jdouble, jboolean,其与java端的数据类型相应例如以下表:

java jni
char jchar
byte jbyte
short jshort
int jint
long jlong
float jfloat
double jdouble
boolean jboolean

对于引用类型则有:jobject, jstring, jthrowable, jclass, jarray, 以及继承于jarray。相应于其原生类型的8种j<type>array和jobjectarray。


知道了不同的数据类型的转换关系。我们就知道在什么情况下,应该对数据进行怎么样的处理。

JNI方法签名





为什么会有方法签名这样的东西呢?这是由于Java这边支持函数重载,即尽管參数不一样。可是方法名一样,那么在JNI层它们的方法名都会是一样的,那JNI也会犯迷糊了。得找哪个呢?

只是也正是由于其參数类型是不一样的。所以就出现了方法签名。利用方法签名和方法名来唯一确定一个JNI函数的调用。

既然方法签名是基于參数类型的不同而形成的,首先要知道Java各数据类型相应的签名是什么,也就是所谓的类型签名,

在jni.h文件里就已经定义了这样一套规则,例如以下:
typedef union jvalue {
jboolean z;
jbyte b;
jchar c;
jshort s;
jint i;
jlong j;
jfloat f;
jdouble d;
jobject l;
} jvalue;

相应于Java端的数据类型,我们也能够看一下以下的表:


Java 类型 类型签名
boolean Z
byte B
char C
short S
int I
long L
float  F
double D
L全限定名;,比方String, 其签名为Ljava/lang/util/String;
数组 [类型签名, 比方 [B

对于上面的类,要注意其后面另一个分号。

而对一个方法,其签名就是其參数类型签名和返回值类型签名的字符串,其形式例如以下:


(类型签名1类型签名2...)返回值类型签名


每一个类型签名之间是没有空格的。以下看看两个样例:

有方法 1):
public string addTail(String tail, int index)

其相应的签名例如以下:


(Ljava/util/String;I)Ljava/util/String;

方法 2):

public int addValue(int index, String value,int[] arr)

其相应的签名例如以下:

(ILjava/util/String;[I)I

相信通过这两个样例,大家也可以了解了方法签名是什么样的形式了吧,对于JNI这些奇形怪状的表示形式也有一定的了解了。


结束。

版权声明:本文博客原创文章,博客,未经同意,不得转载。

Android有关JNI 学习(两)为JNI方法名称,数据类型和方法签名的一些知识的更多相关文章

  1. Android JNI学习(二)——实战JNI之“hello world”

    本系列文章如下: Android JNI(一)——NDK与JNI基础 Android JNI学习(二)——实战JNI之“hello world” Android JNI学习(三)——Java与Nati ...

  2. 【转】基于 Android NDK 的学习之旅-----数据传输(引用数据类型)

    原文网址:http://www.cnblogs.com/luxiaofeng54/archive/2011/08/20/2147086.html 基于 Android NDK 的学习之旅-----数据 ...

  3. Android JNI 学习(一):JNI 简介

    JNI 即 Java Native Interface 是 native 编程接口,它允许在Java虚拟机(VM)内运行Java代码与其他编程语言(主要是C和C++)编写的应用程序和库进行交互操作. ...

  4. Android JNI 学习(二):JNI 设计机制

    本章我们重点说明以下JNI设计的问题,本章中提到的大多数设计问题都与native方法有关.至于调用相关的API的设计,我们会在后面进行介绍. 一.JNI接口函数和指针 native 代码通过调用JNI ...

  5. 基于 Android NDK 的学习之旅-----JNI LOG 打印

    程序都是调出来的. 下面我介绍下JNI层的log打印方法的使用,类似与Android sdk提供的log 1.Android 应用层 MainActivity.java 主要功能代码 a)       ...

  6. Android JNI 学习(三):JNI 数据类型和数据结构

    本文我们来讨论一下JNI如何将Java类型映射到本机C类型. 一.基本数据类型 如下图表整理了Java基本类型和native对应的关系: Java类型 Native类型 描述 boolean jboo ...

  7. 基于 Android NDK 的学习之旅-----JNI 数据类型

    经典老套流程,学编程语言东西,先学它最基础的数据类型,JNI也是如此.JNI 定义了一系列基本数据类型和引用数据类型与java想对应. 1.基本数据类型 下面一张表是描述了 Java 基本数据类型和J ...

  8. 基于 Android NDK 的学习之旅-----数据传输(引用数据类型)

    接着上篇文章继续讲.主要关于引用类型的数据传输,本文将介绍字符串传输和自定义对象的传输. 1.主要流程 1.  String 字符串传输 a)         上层定义一个native的方法,需要一个 ...

  9. 于 Android NDK 的学习之旅-----数据传输(基本数据类型和数组传输)

    之前的一些文章都有涉及到上层和中间层的数据传输,简单来说,也就是参数和返回值的使用.因为中间层要做的最多的也就是数据传输与转换,下面来介绍下这方面的知识. 数据传输可分为 基本数据类型传输 和 引用数 ...

  10. Android JNI学习(五)——Demo演示

    本系列文章如下: Android JNI(一)——NDK与JNI基础 Android JNI学习(二)——实战JNI之“hello world” Android JNI学习(三)——Java与Nati ...

随机推荐

  1. Sort方法的扩展

    OC中类方法中仅仅为我们提供了一些降序方法,如今我们自定义方法,实现升序. 1.要求:定义一个Person类,实例变量包含name,age,height,定义几个对象,把这些对象保存在数组中,自定义方 ...

  2. Windows Phone开发(48):不可或缺的本地数据库

    原文:Windows Phone开发(48):不可或缺的本地数据库 也许WP7的时候,是想着让云服务露两手,故似乎并不支持本地数据库,所有数据都上传上"云"数据库中.不过呢,在SD ...

  3. C#属性总结

    1.私有字段和公有字段的比较 类中的私有字段只能在类的内部访问,而对类的公有字段的访问却不受限制. 在以前,为了封装,程序中会尽量少使用公有字段,因为使用公有字段的话,会让程序失去控制权.所以程序中会 ...

  4. 开源Math.NET基础数学类库使用(16)C#计算矩阵秩

    原文:[原创]开源Math.NET基础数学类库使用(16)C#计算矩阵秩                本博客所有文章分类的总目录:http://www.cnblogs.com/asxinyu/p/4 ...

  5. springmvc如何访问静态文件,例如jpg,js,css

    你怎么DispatcherServlet拦截"*.do"这有一个后缀URL.就不存在訪问不到静态资源的问题.   假设你的DispatcherServlet拦截"/&qu ...

  6. Oracle 学习笔记 17 -- 异常处理(PL/SQL)

    程序异常是在操作期间正常,出现在节目的准备过程是不可避免的例外.但是,必须有一个相应的异常处理机 制,以保证程序的正常运行.PL/SQL程序运行过程中出现的错误.称为异常. 一个优秀的程序都应该可以正 ...

  7. zookeeper集群的python代码测试

    上一篇已经讲解了如何安装zookeeper的python客户端,接下来是我在网上搜到的例子,举例应用环境是: 1.当有两个或者多个服务运行,并且同意时间只有一个服务接受请求(工作),其他服务待命. 2 ...

  8. sails中文文档地址

    http://sailsdoc.swift.ren/ Sails.js是一个Web框架,可以于轻松构建自定义,企业级Node.js Apps.它在设计上类似于像Ruby on Rails的MVC架构的 ...

  9. 【Java基金会】Java整理面试问题和评论(一)

    1. ArrayList,Vector, LinkedList 存储性能及特点 ArrayList 和 Vector 都是使用数组方式存储数据,此数组元素数大于实际存储的数据以便添加和插入元素,它们都 ...

  10. RESTful API Design With NodeJS & Restify

    http://code.tutsplus.com/tutorials/restful-api-design-with-nodejs-restify--cms-22637 The RESTful API ...