JNI使用指南(一)-数据类型

前言

本系列博客可作为JNI参考文档使用,对于初学者,应当在了解了如何在特定平台上(Window、Linux、Android等)搭建JNI开发环境后再来查看。本系列博客主要参考了JNI-API文档,并以此为基础进行扩展。


一、数据类型

本章内容介绍JNI如何进行Java和C的数据映射。

1.1 基本数据类型

下表中的数据为JNI基本数据类型及对应的长度

Java类型JNI类型描述
booleanjbooleanunsigned 8 bits
bytejbytesigned 8 bits
charjcharunsigned 16 bits
shortjshortsigned 16 bits
intjintsigned 32 bits
longjlongsigned 64 bits
floatjfloat32 bits
doublejdouble64 bits
voidvoidvoid

为了向Java那样使用jboolean类型,以下定义了两个宏用来表示Boolean的两个值:

#define JNI_FALSE  0
#define JNI_TRUE   1

整数jsize类型用来描述尺寸等信息:

typedef jint jsize;

1.2 引用类型

JNI除了基本数据类型,还按照了Java的规范定义了若干引用类型:

  • jobject 
    • jclass (java.lang.Class objects)
    • jstring (java.lang.String objects)
    • jarray (arrays) 
      • jobjectArray (object arrays)
      • jbooleanArray (boolean arrays)
      • jbyteArray (byte arrays)
      • jcharArray (char arrays)
      • jshortArray (short arrays)
      • jintArray (int arrays)
      • jlongArray (long arrays)
      • jfloatArray (float arrays)
      • jdoubleArray (double arrays)
    • jthrowable (java.lang.Throwable objects)

如果使用的语言是C,那么在jni.h中,所有的JNI引用类型都使用如下方式声明:

typedef jobject jclass;

如果使用的语言是C++,那么在jni.h中,所有的JNI引用类型都使用如下类方式声明:

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

1.3 属性和方法的ID

方法和属性的ID被声明为C指针类型:

struct _jfieldID;              /* opaque structure */
typedef struct _jfieldID *jfieldID;   /* field IDs */

struct _jmethodID;              /* opaque structure */
typedef struct _jmethodID *jmethodID; /* method IDs */

1.4 值类型

jvalue共用体类型可以保存多种类型的数据,通常用于数组,其定义如下:

typedef union jvalue {
    jboolean z;
    jbyte    b;
    jchar    c;
    jshort   s;
    jint     i;
    jlong    j;
    jfloat   f;
    jdouble  d;
    jobject  l;
} jvalue;

1.5 类型签名

JNI使用签名作为Java虚拟机内容的表示。下表展示了这些签名:

类型签名对应的Java类型
Zboolean
Bbyte
Cchar
Sshort
Iint
Jlong
Ffloat
Ddouble
L全类名;
[ typetype[]
(参数类型签名,…)返回值类型签名方法类型

例如,对于一个方法:

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

这个方法的签名为:

(ILjava/lang/String;[I)J

1.6 使用UTF-8字符串

在JNI中定义了UTF-8的字符串以匹配Java虚拟机中的字符串。UTF-8一个字符的长度不固定,而C语言中使用一个字节表示的ASCII字符。

在UTF-8中,对于单字节仍然采用ASCII码表。表示的字符的取值范围\u0001 到 \u007F,其在内存中存储是下面这个样子:

  • 0xxxxxxx

单字节有效位数为7,第一位始终为0。这里我们可以看出,对于以ASCII编码的字符串可以直接当做UTF-8字符串使用。

对于空字符其表示为\u0000

双字节字符在UTF-8中使用两个字节存放,且字符的开头为11 表示这个一个双字节字符。就先下面这样:

  • 高位: 110xxxxx
  • 低位: 10yyyyyy

对于需要三个字节表示的字符,其最高位使用111表示该字符的字节数。就像下面这样:

  • 高位: 1110xxxx
  • 中位: 10yyyyyy
  • 低位: 10zzzzzz
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值