android设备上如何运行C语言原生程序

前言

咱们知道android设备可以直接运行apk,或者使用dalvikvm指令运行dex文件中的程序, 但是这两者本质上使用的语言都是java或者smali,

如果需要执行C语言程序,我们通常需要借助NDK编译成so库, 那有没有不使用NDK而直接编译c原生程序然后在安卓设备中运行的方式呢?

交叉编译

C语言是一门跨平台的语言,语言跨平台,但是程序不跨平台

也就是说在windows平台下编译的程序只能在windows平台上执行,linux亦是如此, 为什么会出现这种情况呢?

除了操作系统导致的文件格式不一致之外,本质上是因为不同平台cpu使用的架构不一致导致

目前主流的三大cpu架构x86,ARM,MIPS,每个架构都对应着属于自己的一套汇编指令集, 我们编写的程序,最终都会解码成汇编指令被cpu所执行,

那么在windows平台上进行本机编译的C语言代码,会根据当前平台的cpu架构和操作系统生成只能在当前平台运行的程序

如果我想在windows平台编译出能在linux系统或者在ARM设备中运行的程序, 那该怎么办呢?

这个时候我们就要使用交叉编译工具, 那这种编译的模式就不叫本机编译了,而叫做交叉编译

为什么需要交叉编译

场景:

  • 你正在编译一款linux应用,但你手上只有一台windows电脑,这个时候交叉编译能帮上大忙
  • 目标设备环境不允许,比如单片机, 内存和性能无法支持程序的编译
  • 一款配备新硬件的机器问世, 需要借助交叉编译来编译它的系统和编译器等

交叉编译工具

目前主流的交叉编译工具有GCCClang, 接下来主要介绍GCC的使用方法:

首先

交叉编译工具链的命名规则为:arch [-vendor] [-os] [-(gnu)eabi]

  • arch – 体系架构,如ARMMIPS
  • vendor – 工具链提供商
  • os – 目标操作系统
  • eabi – 嵌入式应用二进制接口(Embedded Application Binary Interface)

根据对操作系统的支持与否,ARM GCC可分为支持和不支持操作系统

示例

  • arm-none-eabi:这个是没有操作系统的,适用于ARM架构裸机,工具链提供商未知,嵌入式应用二进制接口,这个工具不支持那些跟操作系统关系密切的函数,比如fork(2)。他使用的是newlib这个专用于嵌入式系统的C库。
  • arm-none-linux-eabi:用于Linux的,ARM架构,使用Glibc

如果是裸机编译,由于没有操作系统进行文件识别翻译,因此编译出来的大部分是面向cpu内核的机器码文件

单片机编译后的文件就是如此

回到主题

我需要用C语言编写一个能在安卓设备上运行的程序, 首先安卓设备大多采用的是ARM架构cpu, 系统采用的是linux系统,

如果我们想在安卓设备中进行本机编译的话,实现起来比较困难, 那么咱们可以借助交叉编译工具,实现在windows平台上编译出能够在ARM+Linux平台上的可执行程序

这里我们使用 arm-none-linux-gnueabi-gcc 这款交叉编译工具

工具下载:

各个平台arm-none-linux-gnueabi交叉编译工具下载

或者

linux平台arm-none-linux-gnueabi工具直链下载

第一步 源码编写

新建test.c文件

1
2
3
4
5
6
7
#include <stdio.h>  

int main()
{
printf("Hello world!\n");
return 0;
}

第二步 源码编译

在命令窗口执行bin包下的arm-none-linux-gnueabi-gcc指令

1
arm-none-linux-gnueabi-gcc test.c -o test -static

因为Android 的 Linux 内核没有标准IO库函数,因此我们采用静态编译的方式进行编译 末尾-static必须要有

第三步 将编译后的可执行文件传至安卓设备

1
adb push test /data/

第四步 执行文件

直接在控制台输入文件名即可执行

1
./test

如果提示权限拒绝,那么执行以下指令:

1
chmod 777 test

至此 程序正常运行 控台输出Hello world!

本文为作者原创 转载时请注明出处 谢谢

乱码三千 – 点滴积累 ,欢迎来到乱码三千技术博客站

0%