JNI基本数据类型

本文是JNI系列的第二篇,介绍JNI中的基本数据类型,以及Java和native的传递约定。

系列文章的大纲如下:

  • JNI 简介
  • JNI 基本类型
  • JNI String
  • JNI 数组
  • JNI 实例变量
  • JNI 静态变量
  • JNI 回调实例方法与静态方法
  • JNI 调用Java中的super.method()
  • JNI 中创建对象
  • JNI 中创建对象数组
  • JNI 中局部引用和全局引用
  • JNI 动态注册
  • 使用Android NDK编译Android的Native库

JNI中的基本数据类型

JNI中的基本类型也称为Native基本类型。

在Java中的基本类型与JNI中的基本类型的对应关系如下:

Java类型Native类型说明
booleanjbooleanunsigned 8 bits
bytejbytesigned 8 bits
charjcharunsigned 16 bits
shortjshortsigned 16 bits
intjintsigned 32 bits
longjlongsigned 64 bits
floatjfloat32 bits
doublejdouble64 bits
voidvoidN/A

在Native中定义了jboolean的两个取值:

#define JNI_FALSE 	0
#define JNI_TRUE  	1

同时还定义jsize类型用于处理索引以及大小:

typedef jint jsize;

以上就是native中的基本类型,以及与Java中基本类型的对应关系,下面就一起来看看如何在Java与native中进行传递吧!

传递基本类型参数

JNI简介中完整的介绍了如果在Java中调用native中的函数。但是并没有传递参数。 在Java与native间传递基本数据类型是十分简单而又直接的,在Java的native方法的参数和返回值,在生成的头文件的函数签名中使用上一节介绍的对应的native类型进行替换,在C/C++的实现中直接使用即可。

实例

我们来看一个实例。

Hello.java

package myjni;

public class Hello {
    static {
        System.loadLibrary("hello");
    }

    public native short addShort(short a, short b);

    public static void main(String[] args) {
        Hello hello = new Hello();
        short a = 1;
        short b = 2;
        System.out.println("addShort(" + a + ", " + b + ") = " + hello.addShort(a, b));
    }
}

如果还不清楚如果生成头文件请参考JNI简介

生成头文件myjni_Hello.h的签名为:

/*
 * Class:     myjni_Hello
 * Method:    addShort
 * Signature: (SS)S
 */
JNIEXPORT jshort JNICALL Java_myjni_Hello_addShort
  (JNIEnv *, jobject, jshort, jshort);

实现函数Java_myjni_Hello_addShort:

JNIEXPORT jshort JNICALL Java_myjni_Hello_addShort(JNIEnv *env, jobject obj, jshort ja, jshort jb) {
  jshort ret = ja + jb;
  return ret;
}

编译生成动态库,并运行Java程序得到输出:

addShort(1, 2) = 3

传递其他数据类型也是一样的操作。注意如果返回true或者false,在native代码中直接使用JNI_FALSE或者JNI_TRUE

类型签名

在生成的头文件中,函数会有如下的注释:

/*
 * Class:     myjni_Hello
 * Method:    addShort
 * Signature: (SS)S
 */

Class和Method的值很容易理解,Signature的值(SS)S是什么含义呢?

这其实是JVM中的类型的表示方法,有如下对应关系:

类型签名Java类型
Zboolean
Bbyte
Cchar
Sshort
Iint
Jlong
ffloat
Ddouble
Vvoid
Lfully-qualified-class;fully-qualified-class
[typetype[]
(arg-types)ret-typemethod type

上表中单个大写字母很好理解,其中的V用于函数返回值。

对于fully-qualified-class,看例子来理解,Java中的String类型的类型签名为Ljava/lang/String;,开头为L,结尾是;

对于Java中的数组,如int[],类型签名为[I

最后一个表示方法的签名,如(SS)S,表示函数参数是两个short类型,返回值是short

括号内SS是函数的参数类型,括号外的S是函数的返回值类型。

如Java中的方法:

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

类型签名为:

(ILjava/lang/String;[I)J

vx搜:极客Furzoom,关注获取第一手资料。

本文完。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

枫竹梦

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值