NDK系列文章(一)—— NDK概览

JNI 简介

  • 名称:Java Native Interface 即Java本地接口
  • 作用:使得Java与本地其他类型语言(如C、C++)交互
  • JNI是Java调用Native语言的一种特性,JNI属于Java的,与Android无直接关系
  • Java通过JNI可以调动由C/C++实现的驱动,从而扩展Java虚拟机

实现步骤:

  • 在java中声明Native方法(即需要调用的本场方法)
  • 编译上述Java源文件(javac得到.class文件)
  • 通过javap命令导出JNI的头文件(.h文件)
  • 编译.so库文件
  • 通过Java命令执行Java程序,最终实现Java调用本地代码

NDK 简介

  • 名称:Native Development Kit,是Android的一个工具开发包
  • 作用:快速开发C、C++的动态库,并自动将so和应用一起打包成APK
  • 在Android的场景下使用JNI,提供了把.so和.apk打包的工具
  • NDK提供的库有限,仅拥有算法效率和敏感的问题
  • 提供了交叉编译器。用于生成特定的CPU平台动态库

NDK和JNI的关系

JNI是实现Java调用C/C++的途径,NDK是Android中实现JNI的手段,即在Android中通过NDK从而实现JNI的功能!

常用C/C++编译器

  • clang:是一个C、C++、Object-C的轻量级编译器。基于LLVM。
  • gcc:GNU C编译器。原本只能处理C语言,现在可以处理C++
  • g++:GNU c++编译器,后缀为.c的源文件,gcc把它当作是C程序,而g++当作是C++程序;后缀为.cpp的,两者都会认为是c++程序,g++会自动链接c++标准库stl,gcc不会,gcc不会定义__cplusplus宏,而g++会
  • GDB:是一个由GNU开源组织发布的、UNIX/Linux操作系统下的、基于命令行的、功能强大的程序调试工具

C/C++文件编译过程

  • 预处理:该阶段主要处理include和define等。它把#include包含进来的.h 文件插入到#include所在的位置,把源程序中使用到的用#define定义的宏用实际的字符串代替

  • 编译:编译阶段,编译器检查代码的规范性、语法错误等。检查无误后,编译器把代码翻译成汇编语言

  • 汇编:汇编阶段把 .s 文件翻译成二进制机器指令文件 .o,这个阶段接收.c、.i、.s的文件都没问题

  • 链接:该阶段链接的是其余的函数库,比如我们自己编写的c/c++文件中用到了三方的函数库,在连接阶段就需要连接三方函数库,如果连接不到就会报错

以上四个阶段可以用对应的命令处理查看:
1、预处理 gcc -E main.c -o main.i
2、编译阶段 gcc -S main.i -o main.s
3、汇编阶段 gcc -c main.s -o main.o
4、链接阶段 gcc main.o -o main.exe

静态库(static libaray .a)和动态链接库(dynamic link library .so)

  • 静态库通常情况下,对函数的链接是放在编译时期(compile time)完成的。所有相关的对象文件(object file)与牵涉到的函数库(library)被链接合成一个可执行文件(executable file)。程序在运行时,与函数库再无瓜葛,因为所有需要的函数已拷贝到自己门下。所以这些函数库被成为静态库(static libaray),通常文件名为“libxxx.a”的形式 Android可以使用静态库
  • 动态库,对一些库函数的链接载入推迟到程序运行的时期(runtime),可以实现进程之间的资源共享。将一些成语升级变得简单,甚至可以真正做到链接载入完全由程序员在程序代码中控制

交叉编译

  • 本地编译:在当前编译平台下,编译出来的程序只能放到当前平台下运行。

比如,我们在 x86 平台上,编写程序并编译成可执行程序。这种方式下,我们使用 x86 平台上的工具,开发针对 x86平台本身的可执行程序,这个编译过程称为本地编译

  • 交叉编译:在当前编译平台下,编译出来的程序能运行在体系结构不同的另一种目标平台上,但是编译平台本身却不能运行该程序。

比如,我们在 x86 平台上,编写程序并编译成能运行在 ARM 平台的程序,编译得到的程序在 x86 平台上是不能运行的,必须放到 ARM 平台上才能运行

交叉编译器的命名规则:

我们在使用交叉编译链时,常常会看到这样的名字:arm-none-linux-gnueabi-gcc、arm-cortex_a8-linux-gnueabi-gcc、mips-malta-linux-gnu-gcc等。这些交叉编译链的命名规则有一定的规则。
arch-core-kernel-system:
arch - - 用于哪个目标平台;
core - - 使用哪个CPU Core, 如Cortex A8, 但也有一些命名比较灵活的,有以厂家或开发版本命名的,还有的直接是none或者cross;
kernel - - 所运行的OS,如Linux、uclinux、bare(无OS);
system - - 交叉编译链所选择的库函数和目标映像的规范,如gun、guneabi等。其中gnu等价于glibc+oabi;gnueabi等价于glibc+eabi

你可能感兴趣的:(NDK)