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
//请按任意键继续. . .
时间: 2024-07-29 23:45:04

JNI(Java Native Interface)_01的相关文章

Android Jni(Java Native Interface)笔记

首先记录一个问题,关于如何用javah生成头文件的. 总是提示“无法访问android.app.Activity”,网上查了说是要指定android.jar的位置,可以在classpath里指定,也可以在命令中直接指定.在windows下两种都试了,都不行.于是装ubuntu.装ubuntu挺麻烦,一开始想用wubi在windows下安装,失败.后来用了某个启动器在硬盘安装.还有分配swap,根目录/,home目录的大小..真是难倒外行人.安装好了之后试了一下,好像还是不行.. 再百度.在csd

JNI(Java Native Interface)_02

JNI(Java Native Interface)_02 ndk开发常用术语 观察jni.h文件的c语言细节: 交叉编译 在一种平台下编译出能够在另外一种平台下运行二进制代码 平台(1,操作系统:windows linux mac os solaris 2,cpu x86 arm mips) 交叉编译原理 源代码--->编译---->动态库(.dll,.so)-->目标平台运行 windows 源代码编译成 linux,arm下的可执行文件 ndk开发工具 ndk (native de

JNI(Java Native Interface)_03

JNI(Java Native Interface)_03 c/c++区别 jni调用: * c: jstring str = (*env)->NewStringUTF(env,getHello()); * c++:jstring str = (env)->NewStringUTF(getHello()); * 区别如下: * 1,c++中把(*env) 的\*号去掉 * 2,调用函数的时候吧参数env去掉 * 3,c中是结构体 c++是类 * 4,c结构体中的函数指针 c++类的成员函数(c

Java固有接口JNI(Java Native Interface)之HelloWorld

1.编写java程序 public class HelloWorld { public native void displayHelloWorld();//所有native关键词修饰的都是对本地的声明 static { System.loadLibrary("hello");//载入本地库 } public static void main(String[] args) { new HelloWorld().displayHelloWorld(); } } 2.编译 javac Hel

Mac下Java JNI (java native interface)调C

1.编写带有native声明的方法的Java类 2.使用javac命令编译编写的Java类 3.使用java -jni className 来生成后缀名为.h的头文件 4.使用其他语言(C.C++)实现本地方法 5.将本地方法编写的文件生成动态链接库 一代码:(不要带包路径) /** * native-0study * * @author xuedui.zhao * @create 2018-04-23 */public class HelloWorld { public native void

android 学习随笔二十七(JNI:Java Native Interface,JAVA原生接口 )

JNI(Java Native Interface,JAVA原生接口) 使用JNI可以使Java代码和其他语言写的代码(如C/C++代码)进行交互. 问:为什么要进行交互? 首先,Java语言提供的类库无法满足要求,且在数学运算,实时渲染的游戏上,音视频处理等方面上与C/C++相比效率稍低. 然后,Java语言无法直接操作硬件,C/C++代码不仅能操作硬件而且还能发挥硬件最佳性能. 接着,使用Java调用本地的C/C++代码所写的库,省去了重复开发的麻烦,并且可以利用很多开源的库提高程序效率.

java native interface JNI 调用Java方法

在上一篇文章中介绍了JNI,以及java调用JNI,这篇讲一下 JNI调用java方法. 通过使用合适的JNI函数,你可以创建Java对象,get.set 静态(static)和 实例(instance)的域,调用静态(static)和实例(instance)函数.JNI通过ID识别域和方法,一个域或方法的ID是任何处理域和方法的函数的必须参数. 下表列出了用以得到静态(static)和实例(instance)的域与方法的JNI函数.每个函数接受(作为参数)域或方法的类,它们的名称,符号和它们对

Java Programming Tutorial Java Native Interface (JNI)

1.  Introduction At times, it is necessary to use native codes (C/C++) to overcome the memory management and performance constraints in Java. Java supports native codes via the Java Native Interface (JNI). JNI is difficult, as it involves two languag

+Java中的native关键字浅析(Java+Native+Interface)++

JNI是Java Native Interface的 缩写.从Java 1.1开始,Java Native Interface (JNI)标准成为java平台的一部分,它允许Java代码和其他语言写的代码进行交互.JNI一开始是为了本地已编译语言,尤其是C和C++而设计的,但是它并不妨碍你使用其他语言,只要调用约定受支持就可以了. 使用java与本地已编译的代码交互,通常会丧失平台可移植性.但是,有些情况下这样做是可以接受的,甚至是必须的,比如,使用一些旧的库,与硬件.操作系统进行交互,或者为了