what 什么是JNI
- JNI java native interface native本地 java本地接口
- 通过JNI可以实现java和本地代码之间相互调用
- jni可以看做是翻译 实际上就是一套协议
![V3$NMB)JUZE4]FJ%{ZRMWF6.png](http://upload-images.jianshu.io/upload_images/2648920-7dd5da93dae5c679.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
why 为什么要用JNI
- Java 一处编译到处运行
- ①java运行在虚拟机上 JNI可以扩展java虚拟机的能力 让java代码可以调用驱动
- ②java是解释型语言 运行效率相对较低 C/C++的效率要高很多 通过jni把耗时操作方法C/C++可以提高java运行效率
- ③ java代码编译成的.class 文件安全性较差, 可以通过jni 把重要的业务逻辑放到c/c++去实现,c/c++反编译比较困难 安全性较高
- C历史悠久 1972年C 通过JNI可以调用优秀的C开源类库
why 为什么要用JNI
- Java 一处编译到处运行
- ①java运行在虚拟机上 JNI可以扩展java虚拟机的能力 让java代码可以调用驱动
- ②java是解释型语言 运行效率相对较低 C/C++的效率要高很多 通过jni把耗时操作方法C/C++可以提高java运行效率
- ③ java代码编译成的.class 文件安全性较差, 可以通过jni 把重要的业务逻辑放到c/c++去实现,c/c++反编译比较困难 安全性较高
- C历史悠久 1972年C 通过JNI可以调用优秀的C开源类库
How 怎么用JNI
- java
- c/c++ 能看懂,会调用
- JNI开发流程 NDK
c 的helloworld
#include<stdio.h> // 相当于 java的import .h c的头文件 stdio.h standard io 标准输入输出
#include<stdlib.h> // stdlib standard library 标准函数库 java.lang
/**
*函数的入口
*/
main(){ // public static void main(String[] args)
printf("helloworld!\n"); //System.out.println(); "\n"换行符
system("javac Hello.java");
system("java Hello");
system("notepad");
system("pause"); //system执行windows的系统命令 ,让控制台暂停
}
C的基本数据类型
* java基本数据类型
boolean 1
byte 1
char 2 char 1个字节
short 2 short 2
int 4 int 4
long 8 long 4
float 4 float 4
double 8 double 8
*c 的基本数据类型
char, int, float, double, long, short, signed, unsigned, void
* signed 有符号数 最高位是符号位 可以表示负数 但是表示的最大值相对要小
* unsigned 无符号数 最高位是数值位 不可以表示负数 表示的最大值相对要大
* signed unsigned 只能用来修饰整形变量 char short int long
* C没有 boolean byte C用0和非0表示false true
C的输出函数
%d - int
%ld – long int
%lld - long long
%hd – 短整型
%c - char
%f - float
%lf – double
%u – 无符号数
%x – 十六进制输出 int 或者long int 或者short int
%o - 八进制输出
%s – 字符串
- 占位符不要乱用 要选择正确的对应类型 否则可能会损失精度
- C字符串
- C没有String类型 C的字符串实际就是字符数组
- C数组定义 [ ]只能再变量名之后
- C字符串两种定义方式
char str[] = {'h','e','l','l','o','\0'};//注意'\0'字符串结束符
char str[] = "你好"; //这种定义方式不用写结束符 可以表示汉字
char *str="abcd";
- 一个汉字是两个字节
C的输入函数
- scanf("占位符", &地址);
- & 取地址符
- C字符串不检查下标越界 使用时要注意
#include<stdio.h>
#include<stdlib.h>
/**
scanf("占位符",内存地址)
*/
main(){
printf("请输入班级的人数:");
int count;
scanf("%d", &count); //&取地址符
printf("班级的人数是%d\n",count);
char cArray[20];//c的数组不检测下标越界
printf("请输入班级的名字:");
scanf("%s",&cArray);
printf("班级的人数是%d,班级的名字%s\n",count,cArray);
printf("count的地址%d\n",&count);
printf("cArray的地址%d\n",&cArray);
system("pause");
}
内存地址的概念
- 声明一个变量,就会立即为这个变量申请内存,一定会有一个对应的内存地址
- 没有地址的内存是无法使用的
- 内存的每一个字节都有一个对应的地址
- 内存地址用一个16进制数来表示
- 32位操作系统最大可以支持4G内存
- 32位系统的地址总线为32位,也就是说系统有2^32个数字可以分配给内存作为地址使用
#include<stdio.h>
#include<stdlib.h>
/**
*/
main(){
//32位操作系统最大支持多大内存 32位地址总线 2^32 byte 4G
int i = 123;
system("pause");
}
实例
#include<stdio.h>
#include<stdlib.h>
/**
*/
main(){
int exp=0;//保存经验
printf("开始打怪升级\n");
while(1){
printf("砍一刀,没砍死!\n");
sleep(2000);
printf("再砍一刀,砍死了 获得经验!\n");
sleep(2000);
exp += 20;
if(exp>2000){
printf("恭喜您升级啦!\n");
break;
}
else{
printf("当前经验值%d,继续砍怪\n",exp);
sleep(2000);
}
}
system("pause");
}