JNI(Java Native Interface)_01

JNI(Java Native Interface)_01

习惯

1、技术是什么?
2、为什么要使用这个技术?
3、怎么使用?
4、实际怎么应用?

jni 是什么

* jni (java native interface)
* 两张不同编程语言之间通讯

java:

特点:一次编写,到处运行
java源代码--->.class--->JVM--->os

c/c++

源代码--->os(01)

java(中国人)---JNI---c/c++(日本人)

jni:两种不同编程语言之间的通讯


为什么要使用jni

*需求(钱):JNI是各种编程语言之间的桥梁
*物联网:刘德华吃绿色猪
*特殊设备(机顶盒、人脸识别):
*高性能(c比java快)
*老板要求(支付宝客户端):java的反编译容易,c不容易

怎么使用jni

*java基础
*c、c++基础
*jni开发

老师演示:
    *使用c语言中的system语句打开java程序:system("java Hello");
    *使用c语言打开本地画板
    *eclipse也是sun公司用java语言编写的,然而打开eclipse.exe的原理其实就是c语言调用java程序jar

java 八种基本数据类型

* byte     1byte
* short    2
* int      4
* long     8
* float    4
* double   8
* char     2
* boolean  1

c 数据类型

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没有指针,但一切对象皆指针。

c的逻辑类型

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 ;
}


jni实际开发经验

利用指针返回多值

方法不能修改实际参数的值:即我们修改不了一个变量所对应的地址值

动态申请内存: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
//请按任意键继续. . .
资料下载
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值