MySQL, Oracle, Linux, 软件架构及大数据技术知识分享平台

网站首页 > 精选文章 / 正文

第三章:JNI类型和数据结构

2025-01-18 20:09 huorong 精选文章 3 ℃ 0 评论

本章讨论了JNI如何将Java类型映射到本机C类型。

本章涵盖以下主题:

  • 基本类型
  • 引用类型
  • 字段和方法ID
  • 值类型
  • 类型签名
  • 修改过的UTF-8字符串

原始类型

下表描述了Java原始类型及其机器相关的native等效类型。

原始类型和native等效类型

Java类型

native类型

描述

boolean

jboolean

无符号8位

byte

jbyte

有符号8位

char

jchar

无符号16位

short

jshort

有符号16位

int

jint

有符号32位

long

jlong

有符号64位

float

jfloat

32位

double

jdouble

64位

void

void

不适用

为了方便起见,提供以下定义。

#define JNI_FALSE  0
#define JNI_TRUE   1

jsize是用于描述基数索引和大小的整数类型:

typedef jint jsize;

引用类型

JNI 包括多个引用类型,对应不同种类的 Java 对象。JNI 引用类型按以下层次结构组织:

  • jobject

jclass(java.lang.Class 对象)

jstring(java.lang.String 对象)

jarray(数组)

jobjectArray(对象数组)

jbooleanArray(布尔数组)

jbyteArray(字节数组)

jcharArray(字符数组)

jshortArray(短整型数组)

jintArray(整型数组)

jlongArray(长整型数组)

jfloatArray(浮点型数组)

jdoubleArray(双精度浮点型数组)

jthrowable(java.lang.Throwable 对象)

在 C 中,所有其他 JNI 引用类型都定义为与 jobject 相同。例如:

typedef jobject jclass;

在 C++ 中,JNI 引入了一组虚类来强制子类型关系。例如:

class _jobject {};
class _jclass : public _jobject {};
// ...
typedef _jobject *jobject;
typedef _jclass *jclass;

字段ID 和 方法ID

方法 ID 和字段 ID 是常规的 C 指针类型:

struct _jfieldID;              /* 不透明结构 */
typedef struct _jfieldID *jfieldID;   /* 字段 ID  */

struct _jmethodID;              /* 不透明结构 */
typedef struct _jmethodID *jmethodID; /* 方法 ID */

值类型

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 VM 的类型签名表示。下表显示了这些类型签名。

Java VM 类型签名

类型签名

Java 类型

Z

boolean

B

byte

C

char

S

short

I

int

J

long

F

float

D

double

L fully-qualified-class ;

fully-qualified-class

[ type

type[]

( arg-types ) ret-type

method type

例如,Java 方法:

long f (int n, String s, int[] arr);

具有以下类型签名:

(ILjava/lang/String;[I)J

修改 UTF-8 字符串

JNI使用修改过的UTF-8字符串来表示各种字符串类型。修改过的UTF-8字符串与Java VM使用的相同。修改过的UTF-8字符串被编码,以便只包含非空ASCII字符的字符序列可以使用每个字符只占用一个字节来表示,但是所有Unicode字符都可以表示。

范围在 \u0001 到 \u007F 内的所有字符用一个字节表示,如下所示:

  • 0xxxxxxx

字节中的七个数据位给出所表示字符的值。

空字符('\u0000')和范围在'\u0080'到'\u07FF'内的字符用一对字节 x 和 y 表示:

  • x: 110xxxxx
  • y: 10yyyyyy

字节表示具有值 ((x & 0x1f) << 6) + (y & 0x3f) 的字符。

范围在'\u0800'到'\uFFFF'内的字符用 3 个字节 x,y 和 z 表示:

  • x: 1110xxxx
  • y: 10yyyyyy
  • z: 10zzzzzz

用字节表示具有值 ((x & 0xf) << 12) + ((y & 0x3f) << 6) + (z & 0x3f) 的字符。

代码点高于 U+FFFF(所谓的补充字符)的字符是通过单独编码其 UTF-16 表示中的两个代理代码单元来表示的。每个代理代码单元由三个字节表示。这意味着,补充字符由六个字节 u,v,w,x,y 和 z 表示:

  • u: 11101101
  • v: 1010vvvv
  • w: 10wwwwww
  • x: 11101101
  • y: 1011yyyy
  • z: 10zzzzzz

用六个字节表示具有值0x10000+((v&0x0f)<<16)+((w&0x3f)<<10)+(y&0x0f)<<6)+(z&0x3f)的字符。

多字节字符的字节以大端(高字节优先)的顺序存储在类文件中。

此格式与标准UTF-8格式之间有两个区别。首先,使用两个字节格式而不是一个字节格式来编码空字符(char)0。这意味着修改过的UTF-8字符串从不包含嵌入的null。其次,仅使用标准UTF-8的一字节、两字节和三字节格式。Java VM不识别标准UTF-8的四字节格式;它使用其自己的两倍三字节格式。有关标准UTF-8格式的更多信息,请参阅Unicode标准第4.0版的第3.9节“Unicode编码表单”。


本文原文地址:
https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/types.html

Tags:native2ascii

控制面板
您好,欢迎到访网站!
  查看权限
网站分类
最新留言