您的位置:首页 > 其它

入门JNI需要知道的(一)

2016-08-21 21:34 92 查看

前言

什么是JNI

java native interface 的简称

在java和本地语言相互调用时,充当两者之间的翻译.

可以看作一种协议(规范),它提供了一套编程框架.

为什么需要JNI

可以很方便的操作底层硬件,例如手机上的传感器等.

提高程序的运行效率,例如2D,3D加速,音视频的解码.

提高程序的安全性,因为本地语言编译之后是二进制的可执行文件(不同的操作系统二进制的可执行文件不同),程序被反编译之后很难看出业务逻辑的具体实现.

方便复用本地开源项目(FFmpeg[多媒体播放器],sqlite,openSSL,openGL,openCV等).

降低程序的移植性等等.

使用需要知道哪些前提

熟悉使用java

了解基本c语言(指针)

熟悉JNI的规范

了解NDK的使用

C

我们应该了解的

两种语言相同的数据类型占用的字节相同时,在传递时不需要进行转换处理.

c语言中没有byte,boolean,c语言中非0为真,0为假.(将所有非零真值中的1代表真).

c语言中的char(1个字节)和long(4个字节)与java有所区别.

c语言中整数类型前面有signed(默认)/ unsigned ,影响着这个整数类型是否能表示负数.

sizeof()是一个运算符,计算数据类型大小,返回它参数的字节数.

内存特点

内存单元的大小是1 byte, 即 8 bits,也就是说:内存单元最大是255.

内存单元排列是线性连续.

进程内存单元个数(即内存大小) 在32位平台下,每个进程拥有4G的内存范围(实际用到的内存会映射到实际内存中).

内存单元编号:也就是内存单元在内存中的地址,是在内存中识别内存单元的唯一编号.

指针

将内存单元的地址(编号)成为指针.

是一个无符号整数(unsigned int),它是一个以当前系统寻址范围为取值范围的整数.

32位系统下寻址能力(地址空间)是4G Bytes(0~2^32-1)二进制表示长度为32bits(也就是4Bytes), unsigned int类型也正好如此取值.

指针变量

普通变量 : 保存数值数据

指针变量 : 专门保存地址的变量(只保存某个变量的第一个内存单元编号,其中变量是连续的地址空间)

我们约定这样表示一个指针变量 : 数据类型 * 指针变量名;

通常指针变量也被叫做指针

指针运算符*和&

&取地址运算符,取变量的地址(编号)

在定义指针变量时使用的 * 是一个类型标志,代表定义的变量是一个指针变量

* 除了在定义指针变量和类型强转时以外的其他情况使用,都代表指针运算符,例如

int i = 0;    //定义普通变量
int *  p = &i;//定义指针变量,*是类型标志,不是指针运算符
// 也可以写成这样 int *p; p = &i;
*p = 30;      // *p <=> i, * 是指针运算符,指向谁就是访问谁
*&i = 20;     // 通过指针访问 *&i <=> i


指针的大小

是确定的,在32位平台下,是4个字节

指针类型和指针的数据类型

//在这样一段代码中
int * p = &i;
//int 是指针的数据类型,它不能影响指针的大小,它代表p所指向的变量的数据类型,决定指针在访问内存时一次存取多少字节
//int * 合起来才是真正的指针类型,代表p是一个指针变量.


二级指针

int main(){
int i = 0;
int* p = &i;    //一级指针保存普通变量的地址
int** pp = &p;  //二级指针保存一级指针地址
i = 10;//变量名访问
printf("i = %d\n",i);
*p = 20;//一级指针访问    *p <=> i
printf("i = %d\n",i);
**pp = 30;// 二级指针访问 **pp <=> *p <=> i
printf("i = %d\n",i);
return 0;
}


指针的运算

指针的运算只有在一段连续的内存空间上才有意义.(即数组)

指针+整数N,指针p向高地址方向移动了N个对象,编号变化p+N*sizeof(对象类型);

因为编译器会自动乘.不需要我们画蛇添足.

指针+整数N也是同样的道理.

数组

数组名:数组名代表数组首元素首地址,是一个常量. 例如int a[5]; a <=> &a[0]

数组元素个数计算方法 sizeof(a) / sizeof(a[0])

指针和数组的关系

根据数组和指针的运算, 我们可以得出: 若int a[5] , int * p = a; 则 a[i] <=> * (a + i) <=> * (p + i) <=> p[i].

因为在C语言中, a[5]会被转换成* (a+i)来编译. 简单来说, 当你看到a[?]时, 请自动脑补* (a+?), 而* (a+i)是不会出现越界的情况,因为无论任何时候, 都是可以加减的. 这样也就解释了为什么C语言不能检查索引越界.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  jni 指针