入门JNI需要知道的(一)

前言

什么是JNI

  • java native interface 的简称
  • 在java和本地语言相互调用时,充当两者之间的翻译.
  • 可以看作一种协议(规范),它提供了一套编程框架.

为什么需要JNI

  • 可以很方便的操作底层硬件,例如手机上的传感器等.
  • 提高程序的运行效率,例如2D,3D加速,音视频的解码.
  • 提高程序的安全性,因为本地语言编译之后是二进制的可执行文件(不同的操作系统二进制的可执行文件不同),程序被反编译之后很难看出业务逻辑的具体实现.
  • 方便复用本地开源项目(FFmpeg[多媒体播放器],sqlite,openSSL,openGL,openCV等).
  • 降低程序的移植性等等.

使用需要知道哪些前提

  • 熟悉使用java
  • 了解基本c语言(指针)
  • 熟悉JNI的规范
  • 了解NDK的使用

C

我们应该了解的

  • 两种语言相同的数据类型占用的字节相同时,在传递时不需要进行转换处理.
  • c语言中没有byte,boolean,c语言中非0为真,0为假.(将所有非零真值中的1代表真).
  • c语言中的char(1个字节)和long(4个字节)与java有所区别.
  • c语言中整数类型前面有signed(默认)/ unsigned ,影响着这个整数类型是否能表示负数.
  • sizeof()是一个运算符,计算数据类型大小,返回它参数的字节数.
  • 内存特点
    1. 内存单元的大小是1 byte, 即 8 bits,也就是说:内存单元最大是255.
    2. 内存单元排列是线性连续.
    3. 进程内存单元个数(即内存大小) 在32位平台下,每个进程拥有4G的内存范围(实际用到的内存会映射到实际内存中).
  • 内存单元编号:也就是内存单元在内存中的地址,是在内存中识别内存单元的唯一编号.
  • 指针
    1. 将内存单元的地址(编号)成为指针.
    2. 是一个无符号整数(unsigned int),它是一个以当前系统寻址范围为取值范围的整数.
    3. 32位系统下寻址能力(地址空间)是4G Bytes(0~2^32-1)二进制表示长度为32bits(也就是4Bytes), unsigned int类型也正好如此取值.
  • 指针变量
    1. 普通变量 : 保存数值数据
    2. 指针变量 : 专门保存地址的变量(只保存某个变量的第一个内存单元编号,其中变量是连续的地址空间)
    3. 我们约定这样表示一个指针变量 : 数据类型 * 指针变量名;
    4. 通常指针变量也被叫做指针
  • 指针运算符*和&

    1. &取地址运算符,取变量的地址(编号)
    2. 在定义指针变量时使用的 * 是一个类型标志,代表定义的变量是一个指针变量
    3. * 除了在定义指针变量和类型强转时以外的其他情况使用,都代表指针运算符,例如

      int i = 0;    //定义普通变量
      int *  p = &i;//定义指针变量,*是类型标志,不是指针运算符
                    // 也可以写成这样 int *p; p = &i;
      *p = 30;      // *p <=> i, * 是指针运算符,指向谁就是访问谁 
      *&i = 20;     // 通过指针访问 *&i <=> i
      
  • 指针的大小
    • 是确定的,在32位平台下,是4个字节
  • 指针类型和指针的数据类型

    //在这样一段代码中
    int * p = &i;
    //int 是指针的数据类型,它不能影响指针的大小,它代表p所指向的变量的数据类型,决定指针在访问内存时一次存取多少字节
    //int * 合起来才是真正的指针类型,代表p是一个指针变量.
    
  • 二级指针

    int main(){
        int i = 0;
        int* p = &i;    //一级指针保存普通变量的地址 
        int** pp = &p;  //二级指针保存一级指针地址 
        i = 10;//变量名访问
        printf("i = %d\n",i);
        *p = 20;//一级指针访问    *p <=> i 
        printf("i = %d\n",i);
        **pp = 30;// 二级指针访问 **pp <=> *p <=> i 
        printf("i = %d\n",i);
        return 0;
    }
    
  • 指针的运算

    • 指针的运算只有在一段连续的内存空间上才有意义.(即数组)
    • 指针+整数N,指针p向高地址方向移动了N个对象,编号变化p+N*sizeof(对象类型);
      因为编译器会自动乘.不需要我们画蛇添足.
    • 指针+整数N也是同样的道理.
  • 数组

    • 数组名:数组名代表数组首元素首地址,是一个常量. 例如int a[5]; a <=> &a[0]
    • 数组元素个数计算方法 sizeof(a) / sizeof(a[0])
  • 指针和数组的关系
    • 根据数组和指针的运算, 我们可以得出: 若int a[5] , int * p = a; 则 a[i] <=> * (a + i) <=> * (p + i) <=> p[i].
    • 因为在C语言中, a[5]会被转换成* (a+i)来编译. 简单来说, 当你看到a[?]时, 请自动脑补* (a+?), 而* (a+i)是不会出现越界的情况,因为无论任何时候, 都是可以加减的. 这样也就解释了为什么C语言不能检查索引越界.
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
提供的源码资源涵盖了Java应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 适合毕业设计、课程设计作业。这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。 所有源码均经过严格测试,可以直接运行,可以放心下载使用。有任何使用问题欢迎随时与博主沟通,第一时间进行解答!
当您在Java程序中需要调用C/C++代码时,可以使用Java Native Interface(JNI)来实现。下面是一个简单的JNI示例,演示了如何将Java方法与C函数相互调用: 1. 创建一个Java类,例如"JNIDemo.java",其中包含您想要调用的本地方法: ```java public class JNIDemo { // 本地方法声明 public native void sayHello(); // 加载本地库 static { System.loadLibrary("jni_demo"); // 加载名为"jni_demo"的本地库 } // 测试 public static void main(String[] args) { JNIDemo demo = new JNIDemo(); demo.sayHello(); // 调用本地方法 } } ``` 2. 在命令行中使用`javac`编译Java类:`javac JNIDemo.java`。 3. 生成C头文件,可以使用`javah`工具:`javah JNIDemo`。这将生成名为"JNIDemo.h"的头文件。 4. 创建一个C源文件,例如"jni_demo.c",实现您在Java中声明的本地方法: ```c #include <stdio.h> #include "JNIDemo.h" JNIEXPORT void JNICALL Java_JNIDemo_sayHello(JNIEnv *env, jobject obj) { printf("Hello from C!\n"); } ``` 5. 在命令行中使用C编译器编译C源文件,并生成共享库文件(DLL或SO): - 对于Windows(使用MinGW):`gcc -shared -I"%JAVA_HOME%\include" -I"%JAVA_HOME%\include\win32" jni_demo.c -o jni_demo.dll` - 对于Linux/Mac:`gcc -shared -I"$JAVA_HOME/include" -I"$JAVA_HOME/include/linux" jni_demo.c -o libjni_demo.so` 注意:请将`$JAVA_HOME`替换为您Java安装的实际路径。 6. 运行Java程序:`java JNIDemo`。您将看到输出:"Hello from C!"。 这是一个简单的JNI示例,演示了如何在Java和C之间进行方法调用。您可以根据自己的需求扩展和定制此示例。希望对您有帮助!

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值