IntelliJ IDEA平台下JNI编程(二)—类型映射

原创 2017年01月12日 17:08:11

转载请注明出处:【huachao1001的专栏:http://blog.csdn.net/huachao1001/article/details/53992258】

这篇文章是直接从《The Java™ Native Interface Programmer’s Guide and Specification》中整理,可以前往http://docs.oracle.com/javase/7/docs/technotes/guides/jni/spec/jniTOC.html中查阅。本文只是作为参考用,并不涉及到深层次的技术。主要是为了后面学习过程中能快速查阅,花半分钟浏览一下即可。

1. JNI类型映射

1.1 基本类型

Java Language Type Native Type Description
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

1.2 引用类型映射

引用类型映射

1.3 jvalue类型

jvalue类型为联合体union类型,它的定义如下:

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

2. 描述符

JNI中使用C语言中的字符串来表示类的名称(class name)、域(field)、方法名以及域和方法描述,这些字符串都是UTF-8编码格式。

2.1 类描述符

类描述符用于描述类或接口名,比如描述java.lang.String类,使用java/lang/String来表示。对于数组类型,则通过[前缀来描述,比如一维数组类型int[],则使用[I表示;二维数组int[][] 则使用[[I表示;甚至三维数组double[][][],则用[[[D表示。

2.2 域描述符(Field descriptors )

八种基本类型对应的域描述符如下:

Field Descriptor Java Language Type
Z boolean
B byte
C char
S short
I int
J long
F float
D double

引用类型的域描述符以字符L开头,再连接引用类型对应的类描述符,最后以分号;结尾。数组类型则是先以[开头,再按照域描述符规则组成,例如:

Field Descriptor Java Language Type
"Ljava/lang/String;" String
"[I" int[]
"[Ljava/lang/Object;" Object[]

2.3 方法描述符(Method descriptors)

方法描述符是描述一个方法(或者说函数),主要描述方法的参数和返回类型,都是通过域描述符进行描述,方法描述符的构成为(形参对应的域描述符)返回类型对应域描述符。并且各个描述符之间没有空格和逗号或者是其他类型的间隔符号。字符V用于表示返回类型为void,而构造函数使用V表示他们的返回类型并且使用<init>作为名字,下表为简单示例:

Method Descriptor Java Language Type
"()Ljava/lang/String;" String f();
"(ILjava/lang/Class;)J" long f(int i, Class c);
`"([B)V" String(byte[] bytes);

3. 宏定义

3.1 JNIEXPORT 与JNICALL

JNIEXPORT 和 JNICALL 都是宏定义,用于指定JNI函数和本地方法实现之间的调用和链接规则。必须将JNIEXPORT放在函数的返回类型之前,将JNICALL放在函数名称与返回类型之间。例如:

JNIEXPORT jint JNICALL Java_pkg_Cls_f(JNIEnv *env, jobject this);

上面为C语言对Java中pkg.Cls.f函数的具体实现对应的函数原型。定义指向Java_pkg_Cls_f函数的指针变量可以如下:

jint (JNICALL *f_ptr)(JNIEnv *env, jobject this);

3.2 JNI_FALSEJNI_TRUE

JNI_FALSEand JNI_TRUE 是定义jboolean类型的两个常量 :

#define JNI_FALSE 0
#define JNI_TRUE 1

3.3JNI_OKJNI_ERR

JNI_OK表示JNI函数成功返回, JNI_ERR有时用于表示错误。

#define JNI_OK 0
#define JNI_ERR (-1)

并非所有的错误情况都是使用JNI_ERR,因为JNI并不指定错误码集合,而是返回JNI_OK表示JNI函数成功返回,返回负数表示函数执行失败。

3.4 JNI_COMMITJNI_ABORT

JNI_COMMITJNI_ABORT两个常量被用于函数中,释放本地拷贝的基本类型数组。JNI_COMMIT 强制要求本地数组数据拷贝至JVM中对应的数组,JNI_ABORT则释放本地数组占用的内存空间,并且不作为新返回数据拷贝至JVM中对应的数组。

#define JNI_COMMIT 1
#define JNI_ABORT 2 
版权声明:本文为博主原创文章,未经博主允许不得转载。

IntelliJ IDEA平台下JNI编程(一)—HelloWorld篇

JNI(Java Native Interface),出于学习JNI的目的,为了能够更方便快速地运行程序。本文的是在IDEA中进行,而不在AndroidStudio,这样能够对NDK的工作过程有个更深...

OpenCV4Android释疑: 透析Android以JNI调OpenCV的三种方式(让OpenCVManager永不困扰)

前文曾详细探讨了关于OpenCV的使用,原本以为天下已太平。

使用 IntelliJ IDEA 和 IntelliJ Clion 进行 JNI 开发

在 Android Studio 开发 JNI 的时候,总感觉被一些细枝末节所迷惑,比如 NDK,.so 文件,动态库,library ,javah 编译等等,感觉很困惑,所以这次打算撇开细枝末节,只...

IntelliJ IDEA平台下JNI编程(四)—本地C代码访问JAVA对象

本文主要针对C代码中访问JVM中对象的普通变量、静态属性、普通函数、静态函数进行举例讲解,通过本文的学习将进一步理解JNIEnv在本地代码和Java之间的重要性。有了前面几篇文章的基础,学习起本文来将...

IntelliJ IDEA平台下JNI编程(五)—本地C代码创建Java对象及引用

本文学习如何在C代码中创建Java对象和对象数组,前面我们学习了C代码中访问Java对象的属性和方法,其实在创建对象时本质上也就是调用构造函数,因此本文知识学习起来也很轻松。有了前面学习数组创建的方法...

自制系列第一季---打造全能视频直播平台(一)

自制系列第一季---打造全能视频直播平台(一)

IntelliJ IDEA平台下JNI编程(三)—字符串、数组

在前面HelloWorld篇中,自动生成的头文件对本地方法声明的形参列表中的第一个参数即为JNIEnv *。那么JNIEnv到底能用来做什么?初学JNI的时候并没有太在意,只满足于Java能调用C代码...

JNI编程之如何传递参数(二)——数组类型的传递

和String一样,JNI为Java基本类型的数组提供了j*Array类型,比如int[]对应的就是jintArray。来看一个传递int数组的例子,Java程序就不写了, JNIEXPORT ji...

Android JNI编程(二)——C语言的基本数据类型,输出函数,输入函数

在学习C语言数据类型之前,我们先来回顾一下Java中的基本数据类型和其特点一:基本数据类型1.在Java中有八大基本数据类型和一个引用数据(String)类型如下:byte 1字节 ch...
  • a_zhon
  • a_zhon
  • 2016年11月22日 15:34
  • 788

JAVA IDE IntelliJ IDEA使用简介(二)—之基本操作

一.在编辑器中打开文件  1.可以使用下面的几种方式打开project内的文件进行编辑  (·)在project窗口中双击需要编辑的文件。  (·)在project窗口选择需要编辑的文件,按F4...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:IntelliJ IDEA平台下JNI编程(二)—类型映射
举报原因:
原因补充:

(最多只允许输入30个字)