下载CLion
安装VS 或 安装MinGW64(编译环境)
CLion安装和配置MinGW:
CLion乱码问题:
#include
const char* poem = "截拳道";
int main() {
std::cout << "Hello, World!" << std::endl;
std::cout << poem << std::endl;
return 0;
}
解决方案
image.png
image.png
解决后效果:
image.png
环境配置好后就,正式进入了...
JNI概述
定义:Java Native Interface,即 Java本地接口
作用: 使得Java 与 本地其他类型语言(如C、C++)交互
JNI是Java调用 Native 语言的一种特性
JNI是属于Java 的,与 Android 无直接关系
实际中的驱动都是C/C++开发的,通过JNI,Java可以调用C/c++实现的驱动,从而扩展Java虚拟机的能力。另外,在高效率的数学运算、游戏的实时渲染、音视频的编码和解码等方面,一般都是用C开发的
(Java代码 里调用 C/C++等语言代码 或 C/C++代码调用Java 代码)
为什么要有 JNI
实际使用中,Java 需要与 本地代码 进行交互
因为 Java 具备跨平台的特点,所以Java 与 本地代码交互的能力非常弱
采用 JNI特性 增强 Java 与 本地代码交互的能力
image.png
image.png
JNI实现步骤:
1.在Java中声明Native方法(即需要调用的本地方法)
2.编译上述 Java源文件javac(得到 .class文件)
3.通过 javah 命令导出JNI的头文件(.h文件)
4.使用 Java需要交互的本地代码 实现在 Java中声明的Native方法
5.编译.so库文件
6.通过Java命令执行 Java程序,最终实现Java调用本地代码
NDK是什么:
NDK(C/C++) SDK(Java)性质是一样的
定义:Native Development Kit,是 Android的一个工具开发包
作用:快速开发C、 C++的动态库,并自动将so和应用一起打包成 APK
提供了把.so和.apk打包的工具
提供了交叉编译器,用于生成特定的CPU平台动态库
提供了很多很多的native支持,就相当于SDK提供了很多上层的支持一样
特点
运行效率高
代码安全性高
功能拓展性好
易于代码复用和移植
NDK是属于 Android 的,与Java并无直接关系
即可通过 NDK在 Android中 使用 JNI与本地代码(如C、C++)交互
即 Android开发的功能需要本地代码(C/C++)实现
NDK与JNI关系
JNI是实现Java调用C/C++的途径,NDK是Android中实现JNI的手段
即在Android的开发环境中,通过NDK从而实现JNI的功能
Java的优点是跨平台,和操作系统之间的调用由JVM完成,但是一些和操作系统相关的操作就无法完成,JNI的出现刚好弥补了这个缺陷,也完善了Java语言,将java扩展得更为强大
常用C/C++编译器
clang
是一个C、C++、Object-C的轻量级编译器。基于LLVM(LLVM是以C++编写而成的构架编译器的框架系统,可以说是一个用于开发编译器相关的库
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++文件中用到了三方的函数库,在连接阶段就需要连接三方函数库,如果连接不到就会报错
预处理
gcc -E main.c -o main.i
编译阶段 (后 汇编代码)
gcc -S main.i -o main.s
汇编阶段 (后 二进制指令代码)
gcc -c main.s -o main.o
链接阶段 (后 可执行程序)
gcc main.o -o main.exe
静态库 动态库 Linux为例:
静态库(static libaray .a)
通常情况下,对函数库的链接是放在编译时期(compile time)完成的。所有相关的对象文件(object file)与牵涉到的函数库(library)被链接合成一个可执行文件(executable file)。程序在运行时,与函数库再无瓜葛,因为所有需要的函数已拷贝到自己门下。所以这些函数库被成为静态库(static libaray),通常文件名为“libxxx.a”的形式
【编译期间 链接时 相关的依赖会全部Copy到静态库中,所以静态库会大一些】
动态链接库(dynamic link library .so)
把对一些库函数的链接载入推迟到程序运行的时期(runtime)
可以实现进程之间的资源共享
将一些程序升级变得简单
甚至可以真正坐到链接载入完全由程序员在程序代码中控制
【动态库在运行时,才会去关联依赖,所以动态库会小一些】
Linux下的.so是基于Linux下的动态链接,其功能和作用类似与windows下.dll文件。
什么是交叉编译
本地编译
在当前编译平台下,编译出来的程序只能放到当前平台下运行,比如,我们在 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)。
systen:交叉编译链所选择的库函数和目标映像的规范,如gnu,gnueabi等。其中gnu等价于glibc+oabi;gnueabi等价于glibc+eabi
必须把这本书给看完才行:JNI编程指南
后半截,后面再补充了 ....