标签:jni
1、技术是什么?
2、为什么要使用这个技术?
3、怎么使用?
4、实际怎么应用?
* jni (java native interface)
* 两张不同编程语言之间通讯
java:
特点:一次编写,到处运行
java源代码--->.class--->JVM--->os
c/c++
源代码--->os(01)
java(中国人)---JNI---c/c++(日本人)
jni:两种不同编程语言之间的通讯
*需求(钱):JNI是各种编程语言之间的桥梁
*物联网:刘德华吃绿色猪
*特殊设备(机顶盒、人脸识别):
*高性能(c比java快)
*老板要求(支付宝客户端):java的反编译容易,c不容易
*java基础
*c、c++基础
*jni开发
老师演示:
*使用c语言中的system语句打开java程序:system("java Hello");
*使用c语言打开本地画板
*eclipse也是sun公司用java语言编写的,然而打开eclipse.exe的原理其实就是c语言调用java程序jar
* byte 1byte
* short 2
* int 4
* long 8
* float 4
* double 8
* char 2
* boolean 1
c的基本数据类型
*char 1byte
*int 4
*float 4
*double 8
*long 4
*short 2
*void
%d -int
输入:
scanf
指针就是地址,地址就是指针
安装cheat Engine,监控软件在内存中的任何一个地址
游戏作弊:扫雷
案例:炸弹倒计时.c
* 1, 连个数相乘 a * b (int a, int b)
* 2, 声明指针变量 数据类型* 变量名;
* 3, 取指针(地址)上的值 *变量名
1、指针的基本语法
int age = 5;//1、先为age分配内存,2、赋值为5
int* page = &age;//page是一个指针变量,该变量可以指向一个int数据的地址
printf("page=%#x,age地址:%#x\n",page,&age);
printf("*page=%d,age地址:%d\n",*page,age);
*号的用法:
1、两个数的相乘
2、声明指针变量 数据类型* 变量名;
3、取指针(地址上)的值
* & 互为逆运算
2、指针的常见错误
什么数据类型的指针变量,只能指向该数据的地址
int a = 3;
float b = 4.4;
int* pa = &a;
int* pb = &b;//float* pb = &b;
//以上的操作导致下面输出*pb=0.0
printf("*pa=%d,*pb=%.1f",*pa,*pb);
以上结论就是:什么类型的数据地址就存放在什么类型的指针变量
//int *p;//指针使用之前要给它赋值,如果不赋值,就是一个野指针。
int* p = 0;//所以要这样初始化--->指针指向了空
或者
int* p = null;//null的值其实就是0
指针变量就是存放数据的地址,数据的地址(0x1122ddAA):四位的十六进制数表示:4个字节
所以说所有的数据类型的指针变量长度都是4字节,长度4
printf("*p的长度:%d\n",sizeof(p));
java没有指针,但一切对象皆指针。
true 非0 FALSE 0
c的实例
void change(int a ,int b){
int c = a;
a = b;
b = c;
}
main(){
int a = 3;
int b = 5;
change(a,b);
printf("%d,%d",a,b);
}
输出3,5 为什么?画内存图:栈内存
void change2(int* pa ,int* pb){
int c = *pa;
*pa = *pb;
*pb = c;
}
main(){
int a = 3;
int b = 5;
change(&a,&b);
printf("%d,%d",a,b);
}
输出:5,3
java的实例(画内存图)
public class Hello
{
static void change2(Integer a,Integer b)
{
Integer c = a;
a = b;
b = c;
}
static void change(int a, int b){
int c = a;
a = b;
b = c;
}
static void change(MyPoint point){
int c = point.x;
point.x = point.y;
point.y = c;
}
public static void main(String[] args)
{
//int a1 = 3;
//int b1 = 5;
//change(a1,b1);
//System.out.println("a1="+a1 + ",b1=" + b1);
//change2(a1,b1);
MyPoint my = new MyPoint();
my.x = 3;
my.y = 5;
change(my);
System.out.println("x="+ my.x + ",y=" + my.y);
}
}
class MyPoint
{
int x;
int y ;
}
利用指针返回多值
方法不能修改实际参数的值:即我们修改不了一个变量所对应的地址值
动态申请内存:int *p1 = malloc(4);//和java中new一个对象很像,申请到的地址,在堆内存
通过free释放空间
学会画C与Java的内存空间图,有助于理解两语言间的底层运行
01.calljava.c
#include <stdio.h> // java 中 import java.util.ArrayList
#include <stdlib.h> // stdio 输入输出头文件 stdlib 标准函数库
main() // public static void main(String[] arg)
{
printf("c Hello world !\n"); // System.out.print(); \n表示换行
system("mspaint");
system("pause");// system函数 直接调用dos命令
}
02.c基本数据类型.c
#include <stdio.h> // java 中 import java.util.ArrayList
#include <stdlib.h> // stdio 输入输出头文件 stdlib 标准函数库
//char
// int float double signed, unsigned, long, short and void
main() // public static void main(String[] arg)
{
signed char i = 156;// -128 ~ 127
printf("i=%d\n",i);
printf("char length:%d\n",sizeof(char));
printf("int length:%d\n",sizeof(int));
printf("float length:%d\n",sizeof(float));
printf("double length:%d\n",sizeof(double));
printf("long long length:%d\n",sizeof(long long));
printf("short length:%d\n",sizeof(short));
printf("Hello world !\n"); // System.out.print(); \n表示换行
system("pause");// system函数 直接调用dos命令
}
//i=-100
//char length:1
//int length:4
//float length:4
//double length:8
//long long length:8
//short length:2
//Hello world !
//请按任意键继续. . .
03.c_函数出栈.c
#include <stdio.h>
#include <stdlib.h>
void changea(int a)
{
a = 100;
}
void changeb(int* pa)
{
*pa = 100;
}
/*
方法不能修改实际参数的值
*/
void change(int* ptemp)
{
int a = 3;
int* pa = &a;
ptemp = pa;
printf("&a=%#x\n",pa);
}
void changec(int** ptemp)
{
//int a = 3;
int *p1 = malloc(4);// malloc(4); 申请到的地址 在堆内存 通过free释放空间
*p1 = 3;
int* pa = p1;
*ptemp = pa;
printf("&a=%#x\n",pa);
free(p1);
}
main()
{
/*
changeb(&num);
printf("num=%d\n",num);
*/
// int num = 5;
int* pnum = 0;
// printf("%d\n",*pnum);
changec(&pnum);
printf("<><><><><><>\n");
printf("<><><><><><>\n");
printf("*pnum=%d,pnum=%#x\n",*pnum,pnum);
system("pause");
}
//&a=0x850f58
//<><><><><><>
//<><><><><><>
//*pnum=8720320,pnum=0x850f58
//请按任意键继续. . .
04.c输出.c
#include <stdio.h> // java 中 import java.util.ArrayList
#include <stdlib.h> // stdio 输入输出头文件 stdlib 标准函数库
/*
%d - int
%ld – long int
%c - char
%f - float
%u – 无符号数
%hd – 短整型
%lf – double
%x – 十六进制输出 int 或者long int 或者short int
%o - 八进制输出
%s – 字符串
*/
main() // public static void main(String[] arg)
{
char str[] = "andy";///{‘a‘,‘n‘,‘d‘,‘y‘,‘\0‘};
int d = 33;
float f = 23.3;
printf("d=%d,f=%.1f,str=%s\n",d,f,str);
printf("Hello world !\n"); // System.out.print(); \n表示换行
system("pause");// system函数 直接调用dos命令
}
//d=33,f=23.3,str=andy
//Hello world !
//请按任意键继续...
05.c输入.c
#include <stdio.h> // java 中 import java.util.ArrayList
#include <stdlib.h> // stdio 输入输出头文件 stdlib 标准函数库
/*
%d - int
%ld – long int
%c - char
%f - float
%u – 无符号数
%hd – 短整型
%lf – double
%x – 十六进制输出 int 或者long int 或者short int
%o - 八进制输出
%s – 字符串
*/
main() // public static void main(String[] arg)
{
printf("学生输入信息:\n");
int sid;
int age;
char name[10];
printf("学号:");
scanf("%d",&sid);
printf("年龄:");
scanf("%d",&age);
printf("名字:");
scanf("%s",&name);
printf("学号:%d,年龄:%d,名字:%s\n",sid,age,name);
system("pause");// system函数 直接调用dos命令
}
//学生输入信息:
//学号:1
//年龄:2
//名字:andy
//学号:1,年龄:2,名字:andy
//请按任意键继续...
05_炸弹倒计时.c
#include <stdio.h> // java 中 import java.util.ArrayList
#include <stdlib.h> // stdio 输入输出头文件 stdlib 标准函数库
main() // public static void main(String[] arg)
{
printf("炸弹离爆炸剩余时间\n"); // System.out.print(); \n表示换行
int time = 100;
printf("time的地址:%#x\n",&time);
for (; time > 0 ; time--)
{
printf("爆炸倒计时:%d\n",time);
sleep(2000);
}
system("pause");// system函数 直接调用dos命令
}
06_指针基本语法.c
#include <stdio.h> // java 中 import java.util.ArrayList
#include <stdlib.h> // stdio 输入输出头文件 stdlib 标准函数库
main() // public static void main(String[] arg)
{
int age = 5;// 1,先为age分配内存, 2,赋值为5 int age; age = 5;
int* page = &age;// page是个指针变量,该变量可以指向一个int数据的地址
// * & 互为逆运算
printf("page=%#x,age地址:%#x\n",page,&age);
printf("*page=%d,age值:%d\n",*page,age);
system("pause");// system函数 直接调用dos命令
}
//page=0x22ff44,age地址:0x22ff44
//*page=5,age值:5
//请按任意键继续。。。
07_指针的常见错误.c
#include <stdio.h> // java 中 import java.util.ArrayList
#include <stdlib.h> // stdio 输入输出头文件 stdlib 标准函数库
main() // public static void main(String[] arg)
{
// 什么数据类型的指针变量 只能指向该数据的地址
//
int a = 3;
float b = 4.4;
int* p = NULL;//指针使用之前要赋值,如果不赋值 野指针
char* c = NULL;
// 指针变量 存放的就是数据的地址 ,数据的地址(0x1122ddAA) 4个字节 ,所有类型的指针变量,长度都是4
if (p == NULL){
printf("p没有指向一个数据的地址");
}
printf("p=%d,c=%d\n",sizeof(p),sizeof(c));
int* pa = &a;// pa 指向 int数据的地址
float* pb = &b;
printf("*pa=%d,*pb=%.1f\n",*pa,*pb);
printf("Hello world !\n"); // System.out.print(); \n表示换行
system("pause");// system函数 直接调用dos命令
}
08_交换两个数据.c
#include <stdio.h> // java 中 import java.util.ArrayList
#include <stdlib.h> // stdio 输入输出头文件 stdlib 标准函数库
void change(int a, int b)
{
int c = a;
a = b;
b = c;
}
void change2(int* pa,int* pb)
{
int c = *pa;
*pa = *pb;
*pb = c;
}
main() // public static void main(String[] arg)
{
int n1 = 2;
int n2 = 3;
change(n1,n2);
printf("n1=%d,n2=%d\n",n1,n2);
change2(&n1,&n2);
printf("n1=%d,n2=%d\n",n1,n2);
system("pause");// system函数 直接调用dos命令
}
//n1=2,n2=3
//n1=3,n2=2
//请按任意键继续. . .
09_指针返回多值.c
#include <stdio.h>
#include <stdlib.h>
void getxy(int* px,int* py)
{
*px = 200;
*py = 250;
}
main()
{
int x ,y ;
getxy(&x,&y);
printf("x=%d,y=%d\n",x,y);
system("pause");
}
//x=200,y=250
//请按任意键继续。。。
10_多级指针.c
#include <stdio.h>
#include <stdlib.h>
main()
{
int i = 5;
int* p1 = &i;
int** p2 = &p1;
// int*** p ; ***p int类型;
printf("i=%d,p1=%d,p2=%d\n",i,*p1,**p2);
system("pause");
}
//i=5,p1=5,p2=5
//请按任意键继续。。。
11_数组.c
#include <stdio.h>
#include <stdlib.h>
void setdatas(int ar[],int len)
{
int i = 0;
for (; i < len; i++)
{
ar[i] = i + 1;
}
}
void printdatas(int ar[],int len)// 形式参数 int ar[], int *ar
{
printf("ar size:%d\n",sizeof(ar));
// int len = sizeof(datas)/sizeof(datas[0]);
int i = 0;
for (; i < len; i++)
{
printf("ar[%d]=%d,&ar[%d]=%#x\n",i,ar[i],i,&ar[i]);
}
}
void printp(int* ar,int len)
{
printf("ar size:%d\n",sizeof(ar));//输出4字节,这是地址的长度
// int len = sizeof(datas)/sizeof(datas[0]);
int i = 0;
for (; i < len; i++)// *(ar+i) 等价于 ar[i] 对指针变量加1 以指针类型为单位 如: int* 1 4byte short* 1 2byte
{
printf("ar[%d]=%d,&ar[%d]=%#x\n",i,*(ar + i),i,&ar[i]);
}
}
main()
{
//datas 表示数组第一个元素地址的常量
int datas[5]; // int datas[] = new int[5];
setdatas(datas,5);
printdatas(datas,5);
datas[5] = 33;
printp(datas,6);
printf("datas length:%d\n",sizeof(datas)/sizeof(datas[0]));
system("pause");
}
//ar size:4
//ar[0]=1,&ar[0]=0x22ff20
//ar[1]=2,&ar[1]=0x22ff24
//ar[2]=3,&ar[2]=0x22ff28
//ar[3]=4,&ar[3]=0x22ff2c
//ar[4]=5,&ar[4]=0x22ff30
//ar size:4
//ar[0]=1,&ar[0]=0x22ff20
//ar[1]=2,&ar[1]=0x22ff24
//ar[2]=3,&ar[2]=0x22ff28
//ar[3]=4,&ar[3]=0x22ff2c
//ar[4]=5,&ar[4]=0x22ff30
//ar[5]=33,&ar[5]=0x22ff34
//datas length:5
//请按任意键继续. . .
12_short数组.c
#include <stdio.h>
#include <stdlib.h>
void initdatas(short *a)
{
printf("a size:%d\n",sizeof(a));
}
main()
{
/*
指针变量加减1的单位 1 看指针的数据类型 如 int* 1 4byte
仅限于数组
*/
short datas[5]; //datas 等价于 &datas[0]
initdatas(datas);
printf("datas length:%d\n",sizeof(datas));//10
short* p = datas;// short* p = &datas[0] ;
printf("datas length:%d\n",sizeof(p));//4
//为什么他们有这种区别,因为当他们在实参中就有这种区别,但是如果在形参中就没有任何区别
int i = 0;
for (; i < 5; i++)
{
printf("&p[%d]=%#x,p[%d]=%d\n",i,p + i,i,*(p++));// (p + i) 等价于 &p[i]
}
system("pause");
}
//a size:4
//datas length:10
//datas length:4
//&p[0]=0x22ff32,p[0]=212
//&p[1]=0x22ff36,p[1]=0
//&p[2]=0x22ff3a,p[2]=8752
//&p[3]=0x22ff3e,p[3]=80
//&p[4]=0x22ff42,p[4]=53
//请按任意键继续. . .
13_指针与字符串.c
#include <stdio.h>
#include <stdlib.h>
main()
{
char str[] = {‘a‘,‘b‘};//"hello\0world";// 字符串有结束符\0
printf("str[]length:%d, strlength = %d\n",sizeof(str),strlen(str));
system("pause");
}
//str[]length:2, strlength = 5
//请按任意键继续. . .
14_学号管理系统.c
#include <stdio.h>
#include <stdlib.h>
void printstus(int* s,int len)
{
int i = 0;
for (; i < len ; i++)
{
printf("第%d个学生的学号为:%d\n",i + 1,s[i]);
}
//printf("");
}
main()
{
printf("欢迎使用学生学籍管理系统\n");
int number;//学生的数量
printf("请输入录入学生的数量:");
scanf("%d",&number);
if (number < 1)
{
printf("请按套路出牌\n");
system("pause");
return;
}
//输入合法的数字
int* stus = malloc(number * sizeof(int)); //动态申请内存(在堆)
// int stus[number];
int i = 0;
for (; i < number;i++)
{
printf("请输入第%d个学生学号:",(i + 1));
scanf("%d",stus+i);
}
int type ;
printf("%d个学号已经输入完毕,查看学生请输入1,追加输入学生请输入2\n 请输入:",number);
scanf("%d",&type);
if (type == 1)
{
printstus(stus,number);
} else if (type != 2){
printf("请按套路出牌\n");
system("pause");
return;
} else { // thype 2
int numapp;//学生的数量
printf("请输入录入学生的数量:");
scanf("%d",&numapp);
stus = realloc(stus,(number + numapp) * sizeof(int)); //追加内存,在原理的内存基础上追加内存个数
for (; i < number + numapp;i++)
{
printf("请输入第%d个学生学号:",(i + 1));
scanf("%d",stus+i);
}
printstus(stus,number + numapp);
}
system("pause");
}
//欢迎使用学生学籍管理系统
//请输入录入学生的数量:3
//请输入第1个学生学号:110
//请输入第2个学生学号:120
//请输入第3个学生学号:130
//3个学号已经输入完毕,查看学生请输入1,追加输入学生请输入2
// 请输入:2
//请输入录入学生的数量:2
//请输入第4个学生学号:140
//请输入第5个学生学号:150
//第1个学生的学号为:110
//第2个学生的学号为:120
//第3个学生的学号为:130
//第4个学生的学号为:140
//第5个学生的学号为:150
//请按任意键继续. . .
15_结构体.c
#include <stdio.h>
#include <stdlib.h>
int add(int a, int b)
{
return a + b;
}
int mul(int a, int b)
{
return a * b;
}
struct Student
{
int id; // 4
char sex;// 1
short age;// 2
char *name;//4
int (*op)(int a, int b);
};
// c 结构体 只能属性 不能声明方法
typedef struct Student STU;
typedef int haha;
main()
{
STU s1 = {101,‘m‘,22,"andy",add};
s1.id = 1011;
STU* ps = &s1;
printf("ps size=%d\n",sizeof(s1));
printf("stu.id=%d\n",ps->id);//(*ps).id
int res = s1.op(4,6);
printf("res=%d\n",res);
system("pause");
}
//ps size=16
//stu.id=1011
//res=10
//请按任意键继续. . .
16_函数指针.c
#include <stdio.h>
#include <stdlib.h>
int add(int a, int b)
{
return a + b;
}
int mul(int a, int b)
{
return a * b;
}
main()
{
int (*op)(int a, int b);// op函数指针变量
op = mul;
int res = (*op)(3,5);
printf("res=%d\n",res);
system("pause");
}
//res=15
//请按任意键继续. . .
17_联合体.c
#include <stdio.h>
#include <stdlib.h>
union Data
{
char c;
int num;
short s;
};
main()
{
//公共体(联合体) 以成员的最大数据类型,作为该联合体的长度
union Data d;
printf("%d\n",sizeof(d));
d.num = 0x11221361;
printf("%hd\n",d.s);
printf("%d\n",d.num);
printf("%c\n",d.c);
system("pause");
}
//4
//4961
//287445857
//a
//请按任意键继续. . .
18_枚举.c
#include <stdio.h>
#include <stdlib.h>
enum Color
{
red=1,black,green,yellow,cyan,blue
};
main()
{
enum Color c;
c = yellow;
printf("%d\n",c);
system("pause");
}
//4
//请按任意键继续. . .
19_宏定义.c
#include <stdio.h>
#include <stdlib.h>
#define null 0
#define mul(a,b) ((a) * (b))
main()
{
printf("%d\n",mul(3 + 2,2 + 4) * 3);// add(3,4) a + b > 3 + 2 * 2 + 4 * 3
//printf("str[]length:%d, strlength = %d\n",sizeof(str),strlen(str));
system("pause");
}
//90
//请按任意键继续. . .
20_静态变量.c
#include <stdio.h>
#include <stdlib.h>
void add()
{
static int i = 5;
i++;
printf("i=%d\n",i);
}
main()
{
add();
add();
system("pause");
}
//i=6
//i=7
//请按任意键继续. . .
标签:jni
原文地址:http://blog.csdn.net/faith_yee/article/details/44854771