@cxm-2016
2016-11-15T15:02:18.000000Z
字数 2206
阅读 8258
JNI完全指南
版本:1
作者:陈小默
声明:禁止商业,禁止转载
本系列博客可作为JNI参考文档使用,对于初学者,应当在了解了如何在特定平台上(Window、Linux、Android等)搭建JNI开发环境后再来查看。本系列博客主要参考了JNI-API文档,并以此为基础进行扩展。水平不足,如有错误,恳请批评指正。
本章内容介绍JNI如何进行Java和C的数据映射。
下表中的数据为JNI基本数据类型及对应的长度
Java类型 | JNI类型 | 描述 |
---|---|---|
boolean | jboolean | unsigned 8 bits |
byte | jbyte | signed 8 bits |
char | jchar | unsigned 16 bits |
short | jshort | signed 16 bits |
int | jint | signed 32 bits |
long | jlong | signed 64 bits |
float | jfloat | 32 bits |
double | jdouble | 64 bits |
void | void | void |
为了向Java那样使用jboolean类型,以下定义了两个宏用来表示Boolean的两个值:
#define JNI_FALSE 0
#define JNI_TRUE 1
整数jsize类型用来描述尺寸等信息:
typedef jint jsize;
JNI除了基本数据类型,还按照了Java的规范定义了若干引用类型:
如果使用的语言是C,那么在jni.h中,所有的JNI引用类型都使用如下方式声明:
typedef jobject jclass;
如果使用的语言是C++,那么在jni.h中,所有的JNI引用类型都使用如下类方式声明:
class _jobject {};
class _jclass : public _jobject {};
// ...
typedef _jobject *jobject;
typedef _jclass *jclass;
方法和属性的ID被声明为C指针类型:
struct _jfieldID; /* opaque structure */
typedef struct _jfieldID *jfieldID; /* field IDs */
struct _jmethodID; /* opaque structure */
typedef struct _jmethodID *jmethodID; /* method IDs */
jvalue共用体类型可以保存多种类型的数据,通常用于数组,其定义如下:
typedef union jvalue {
jboolean z;
jbyte b;
jchar c;
jshort s;
jint i;
jlong j;
jfloat f;
jdouble d;
jobject l;
} jvalue;
JNI使用签名作为Java虚拟机内容的表示。下表展示了这些签名:
类型签名 | 对应的Java类型 |
---|---|
Z | boolean |
B | byte |
C | char |
S | short |
I | int |
J | long |
F | float |
D | double |
L全类名; | 类 |
[ type | type[] |
(参数类型签名,...)返回值类型签名 | 方法类型 |
例如,对于一个方法:
long f (int n, String s, int[] arr);
这个方法的签名为:
(ILjava/lang/String;[I)J
在JNI中定义了UTF-8的字符串以匹配Java虚拟机中的字符串。UTF-8一个字符的长度不固定,而C语言中使用一个字节表示的ASCII字符。
在UTF-8中,对于单字节仍然采用ASCII码表。表示的字符的取值范围\u0001
到 \u007F
,其在内存中存储是下面这个样子:
单字节有效位数为7,第一位始终为0。这里我们可以看出,对于以ASCII编码的字符串可以直接当做UTF-8字符串使用。
对于空字符其表示为\u0000
。
双字节字符在UTF-8中使用两个字节存放,且字符的开头为11 表示这个一个双字节字符。就先下面这样:
对于需要三个字节表示的字符,其最高位使用111表示该字符的字节数。就像下面这样:
下一篇:JNI完全指南(二)——类与异常
[1]ORACLE guides for JNI——Chapter 3: JNI Types and Data Structures