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
//請按任意鍵繼續. . .
資料下載
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章