java ndk c语言_00_Android NDK概要与C语言简介

下载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;

}

解决方案

1233735fa19b

image.png

1233735fa19b

image.png

解决后效果:

1233735fa19b

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 与 本地代码交互的能力

1233735fa19b

image.png

1233735fa19b

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编程指南

后半截,后面再补充了 ....

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值