• Android——C语言、JNI与低层调用


    JNI

      java native interface

    c的基本数据类型

    • int:32位,能表示的数字是2的32次方个
    • 最高位用来表示符号位,那么还剩下31位可以表示数值,所以能表示的数字就是2的31次方个
    • int的表示范围:
      • 当最高位是0时:0~2147483647
      • 当最高位是1是:-2147483648~-1

        java的基本数据类型长度

        c的基本数据类型长度

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

    *的三种用法

    1. 乘法
    2. int* p: 定义一个指针变量p,p中存放一个内存地址,这个地址所存放的数据规定是int型
    3. *p:  取出p中保存的内存地址存放的数据

    数据传递

    • 所有语言所有平台,都只有值传递,引用传递 传递的值是内存地址

    • 系统自动分配和释放
    • 保存全局、静态、局部变量
    • 在栈上分配内存叫静态分配
    • 大小一般是固定的

    • 程序员手动分配(malloc/new)和释放(free/java不用手动释放)
    • 在堆上分配内存叫动态分配
    • 一般硬件内存有多大就有多大

    交叉编译

    • 在一个平台下,编译出另一个平台能够执行的二进制的代码
    • 平台:windows,mac os,linux
    • 处理器:x86,arm,mips

    交叉编译的原理

    • 源代码->编译->链接->可执行程序
    • 模拟其他平台的特性

    交叉编译的工具链

    • 多个工具的集合,一个工具使用完后接着调用下一个工具

    常见工具

    • NDK:native developement kit:开发jni必备,就是模拟其他平台特性来编译代码的工具
    • CDT:C/C++ developement tools:高亮显示c语言关键字
    • cygwin:一个模拟器,可以再windows下运行linux指令

    NDK目录结构

    • docs:帮助文档
    • build/tools:linux的批处理文件
    • platforms:编译c代码需要使用的头文件和类库
    • prebuilt:预编译使用的二进制可执行文件
    • sample:jni的使用例子
    • source:ndk的源码
    • toolchains:工具链
    • ndk-build.cmd:编译打包c代码的一个指令

    使用jni

    1. 在项目根目录下创建jni文件夹
    2. 在jni文件中创建一个c文件
    3. 在java代码中,创建一个本地方法helloFromC

      public native String helloFromC();
    4. 在jni中定义函数实现这个方法,函数名必须为

      jstring Java_com_example_helloworld1_MainActivity_helloFromC(JNIEnv* env, jobject obj)
    5. 返回一个字符串,用c定义一个字符串

      char* cstr = "hello from c";
    6. 把c的字符串转换成java的字符串

      jstring jstr = (*env)->NewStringUTF(env, cstr);
      return jstr;
    7. 在jni中创建Android.mk文件
    8. 在c文件中添加<jni.h>头文件
    9. 在jni文件夹下执行ndk-build.cmd指令
    10. java代码中加载so类库,调用本地方法

    常见错误

    • findLibrary returned null

      • CPU平台不匹配
      • 加载类库时,写错类库名字
    • 本地方法找不到

      • 忘记加载类库
      • c代码中方法名写错了

    javah

    *1.7:在src目录下执行javah 包名.类名 *1.6:在bin/classes目录下执行

    javap

    • 在bin/class目录下执行javap -s 包名.类名
      • 打印方法签名

    C向C++改造

    1. 把c文件后缀名换成cpp
    2. Android.mk文件中的hello.c也要换成hello.cpp
    3. c++的使用的环境变量结构体中,访问了c使用的结构体的函数指针,函数名全部都是一样的,只是参数去掉了结构体指针
    4. 访问函数指针时,把env前面的*号去掉,因为此时env已经是一级指针
    5. clean,清除之前编译的残留文件
    6. 把声明函数的h文件放入jni文件夹中,include该h文件
  • 相关阅读:
    Qt串口的使用记录
    CImage灰度化
    (记录)MSYS2+MINGW32编译ffmpeg过程
    Blas 基本函数功能
    blas中dgemm_的用法
    选择、插入、冒泡排序
    简单的页面
    中国大学排名
    爬bing 主页
    读书报告
  • 原文地址:https://www.cnblogs.com/jesonjason/p/5425516.html
Copyright © 2020-2023  润新知