热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

交叉编译和库文件

编译器到底干了什么1.什么是源文件2.什么是可执行文件2.1为什么可执行文件可以执行2.2可执行文件的内容3.编译器3.1不同种类的编译器3.2交叉编译4.如何从源文件到可执行文件

编译器到底干了什么

  • 1. 什么是源文件
  • 2. 什么是可执行文件
    • 2.1 为什么可执行文件可以执行
    • 2.2 可执行文件的内容
  • 3. 编译器
    • 3.1 不同种类的编译器
    • 3.2 交叉编译
  • 4. 如何从源文件到可执行文件
    • 4.1 链接
    • 4.2 库文件
    • 4.3 DLL文件
    • 4.4 导入库
    • 4.5 静态链接库
  • 参考链接
  • 扩展链接

一直以来,我一直有个疑惑:编写程序为什么需要编译器。通过搜索,我知道了编译器可以将源代码编译生成可执行文件。下面本文将介绍从源代码到可执行文件的变化过程。

1. 什么是源文件

程序员可以使用 C 语言、C++、Java 等各种编程语言编写代码,保存代码的文件就是源文件。源文件其实是一种文本文件,所以理论上任何文本编辑器都可以编写源代码,哪怕是 Windows 下的记事本工具也可以。

下面给出一个源文件的示例,hello.cpp 。
在这里插入图片描述

2. 什么是可执行文件

可执行文件 (executable file) 指的是可以由操作系统进行加载执行的文件。不同的操作系统,可执行文件的后缀名不同。在windows操作系统下, .exe文件是非常常见的可执行程序。
其实我并不关心可执行文件的后缀名是什么,我关心的是可执行文件中的内容是什么,为啥这个文件可以被执行

2.1 为什么可执行文件可以执行

正如我们所知道的,CPU 是计算机的大脑。计算机是通过 CPU 执行程序的。程序员编写的源文件本质上就是文本文件,因此是不可以被 CPU 执行的。CPU 只能解析并运行转换为本地代码的程序内容。不论源代码是用什么编程语言编写的,最后都要转换成本地代码。计算机只能运行本地代码。
那么问题来了,什么是本地代码?简单来说,本地代码就是可执行文件中的内容。

2.2 可执行文件的内容

首先来看下可执行文件中到底有什么。通过编译器,hello.cpp 被编译生成了 hello.exe 文件。用记事本打开 hello.exe 文件,结果如下图所示,是一堆人类理解不了的乱码,如果转为 16 进制,则是一些数值。

在这里插入图片描述

十六进制格式的可执行文件类似下图。如果想查看可执行文件的十六进制,可以参考以下经验。

在这里插入图片描述

3. 编译器

现在我们知道了,程序员编写的源代码通过编译器可以转换为计算机可以执行的本地代码。现实生活中,程序员可以采用不同的编程语言编写代码,同样编写好的程序也可以运行在不同的计算机上(CPU)。那么编译器是如何实现这一转换过程的呢?

3.1 不同种类的编译器

不同的编程语言对应有不同的编译器,例如:负责将 C 语言编写的源代码转换为本地代码的编译器,被称为 C 编译器。
不同类型的 CPU 也会生成不同类型的本地代码,例如:x86 系列的编译器。
不同运行环境下的编译器,例如:Windows 用的 C 编译器, Linux 用的 C 编译器。因为编译器本身也是一种程序,所以需要考虑运行环境。

3.2 交叉编译

交叉编译是嵌入式开发中非常常见的一个名词。简单来说,交叉编译是指在一个平台上生成另一个平台上的可执行代码。例如:在 x86 平台上,编译生成能运行在 ARM 平台的程序。
交叉编译器就是用来交叉编译的。交叉编译与本地编译不同,本地编译是指在当前编译平台下,编译生成的程序只能在本地平台运行。例如:在 x86 平台上编译生成针对 x86 平台本身的可执行程序。交叉编译生成的是针对目标平台的程序,因而不能在当前编译平台下运行。

4. 如何从源文件到可执行文件

编译器兼具编译链接两个功能。源代码通过编译后会生成扩展名为 .obj 的目标文件,里面的内容是本地代码。

4.1 链接

链接是指将多个目标文件结合,生成一个 EXE 文件的处理。链接器就是负责链接的程序。链接时需要源代码对应的目标文件和程序的启动。程序的启动也是一个目标文件,里面记述了和所有程序起始位置相结合的处理内容,它是由编译器提供的 .obj 文件。即使程序不调用其他目标文件的函数,也必须要进行链接,和启动结合起来。

4.2 库文件

为了简化链接器参数指定多个目标文件这一过程,库文件应运而生。例如: import32 .lib 就是一个库文件。库文件是多个目标文件的集合,链接器指定库文件后,会从库文件中抽取需要的目标文件,和其他目标文件结合生成 EXE 。库文件中包含的函数被称为标准函数,采用库文件提供函数可以不公开函数的源码。
如果链接时,不指定相应的库文件,链接器就会报错。错误消息一般为:无法解析的外部符号。 也就是说,无法找到记录目的变量和函数的目标文件,因而无法链接。

4.3 DLL文件

Windows 为应用提供了函数的形式的接口 API(Application Programming Interface)。API 本质上是 Windows 提供的一种函数,但它不是标准函数。API的目标文件被存储在 DLL (dynamic link library)中,DLL 文件是程序运行时动态结合的文件,它的扩展名为 .dll ,它本质上是一种特殊的库文件。

4.4 导入库

如果一个 .lib 文件中仅存储着信息,如:import32.lib 中仅存储两个信息,MessageBox() 在 user32.dll 这个 DLL 文件中,存储着 DLL 文件的文件夹信息, 而 MessageBox() 目标文件的实体实际并不存在。类似 import32.lib 这样的库文件则称为导入库

4.5 静态链接库

存储着目标文件实体,并直接和 EXE 文件结合的库文件形式称为 静态链接库。
为了方便理解,下图给出了 Windows 中编译和链接机制。

在这里插入图片描述

参考链接
  1. 如何使用Notepad++工具查看文件的十六进制
  2. 交叉编译详解 一 概念篇
  3. 程序是怎样跑起来的

扩展链接
  • dll的两种调用方式,lib与dll区别

推荐阅读
  • 本文概述了JNI的原理以及常用方法。JNI提供了一种Java字节码调用C/C++的解决方案,但引用类型不能直接在Native层使用,需要进行类型转化。多维数组(包括二维数组)都是引用类型,需要使用jobjectArray类型来存取其值。此外,由于Java支持函数重载,根据函数名无法找到对应的JNI函数,因此介绍了JNI函数签名信息的解决方案。 ... [详细]
  • Android Studio Bumblebee | 2021.1.1(大黄蜂版本使用介绍)
    本文介绍了Android Studio Bumblebee | 2021.1.1(大黄蜂版本)的使用方法和相关知识,包括Gradle的介绍、设备管理器的配置、无线调试、新版本问题等内容。同时还提供了更新版本的下载地址和启动页面截图。 ... [详细]
  • 计算机存储系统的层次结构及其优势
    本文介绍了计算机存储系统的层次结构,包括高速缓存、主存储器和辅助存储器三个层次。通过分层存储数据可以提高程序的执行效率。计算机存储系统的层次结构将各种不同存储容量、存取速度和价格的存储器有机组合成整体,形成可寻址存储空间比主存储器空间大得多的存储整体。由于辅助存储器容量大、价格低,使得整体存储系统的平均价格降低。同时,高速缓存的存取速度可以和CPU的工作速度相匹配,进一步提高程序执行效率。 ... [详细]
  • imx6ull开发板驱动MT7601U无线网卡的方法和步骤详解
    本文详细介绍了在imx6ull开发板上驱动MT7601U无线网卡的方法和步骤。首先介绍了开发环境和硬件平台,然后说明了MT7601U驱动已经集成在linux内核的linux-4.x.x/drivers/net/wireless/mediatek/mt7601u文件中。接着介绍了移植mt7601u驱动的过程,包括编译内核和配置设备驱动。最后,列举了关键词和相关信息供读者参考。 ... [详细]
  • C++字符字符串处理及字符集编码方案
    本文介绍了C++中字符字符串处理的问题,并详细解释了字符集编码方案,包括UNICODE、Windows apps采用的UTF-16编码、ASCII、SBCS和DBCS编码方案。同时说明了ANSI C标准和Windows中的字符/字符串数据类型实现。文章还提到了在编译时需要定义UNICODE宏以支持unicode编码,否则将使用windows code page编译。最后,给出了相关的头文件和数据类型定义。 ... [详细]
  • CentOS 7部署KVM虚拟化环境之一架构介绍
    本文介绍了CentOS 7部署KVM虚拟化环境的架构,详细解释了虚拟化技术的概念和原理,包括全虚拟化和半虚拟化。同时介绍了虚拟机的概念和虚拟化软件的作用。 ... [详细]
  • Java在运行已编译完成的类时,是通过java虚拟机来装载和执行的,java虚拟机通过操作系统命令JAVA_HOMEbinjava–option来启 ... [详细]
  • 服务器上的操作系统有哪些,如何选择适合的操作系统?
    本文介绍了服务器上常见的操作系统,包括系统盘镜像、数据盘镜像和整机镜像的数量。同时,还介绍了共享镜像的限制和使用方法。此外,还提供了关于华为云服务的帮助中心,其中包括产品简介、价格说明、购买指南、用户指南、API参考、最佳实践、常见问题和视频帮助等技术文档。对于裸金属服务器的远程登录,本文介绍了使用密钥对登录的方法,并提供了部分操作系统配置示例。最后,还提到了SUSE云耀云服务器的特点和快速搭建方法。 ... [详细]
  • Oracle优化新常态的五大禁止及其性能隐患
    本文介绍了Oracle优化新常态中的五大禁止措施,包括禁止外键、禁止视图、禁止触发器、禁止存储过程和禁止JOB,并分析了这些禁止措施可能带来的性能隐患。文章还讨论了这些禁止措施在C/S架构和B/S架构中的不同应用情况,并提出了解决方案。 ... [详细]
  • 嵌入式处理器的架构与内核发展历程
    本文主要介绍了嵌入式处理器的架构与内核发展历程,包括不同架构的指令集的变化,以及内核的流水线和结构。通过对ARM架构的分析,可以更好地理解嵌入式处理器的架构与内核的关系。 ... [详细]
  • 乐视手机S1 Pro发布,声称手机真不卡,外观酷似iPhone
    乐视宣布即将发布乐视手机S1 Pro,搭载虎贲T7510芯片,声称手机真不卡。该手机外观与iPhone 14 Pro相似,采用居中药丸式挖孔屏和方形三摄模组。官方定位该手机为便宜的5G手机,售价预计在千元价位。 ... [详细]
  • 如何在服务器主机上实现文件共享的方法和工具
    本文介绍了在服务器主机上实现文件共享的方法和工具,包括Linux主机和Windows主机的文件传输方式,Web运维和FTP/SFTP客户端运维两种方式,以及使用WinSCP工具将文件上传至Linux云服务器的操作方法。此外,还介绍了在迁移过程中需要安装迁移Agent并输入目的端服务器所在华为云的AK/SK,以及主机迁移服务会收集的源端服务器信息。 ... [详细]
  • 本文介绍了2020年计算机二级MSOffice的选择习题及答案,详细解析了操作系统的五大功能模块,包括处理器管理、作业管理、存储器管理、设备管理和文件管理。同时,还解答了算法的有穷性的含义。 ... [详细]
  • 海马s5近光灯能否直接更换为H7?
    本文主要介绍了海马s5车型的近光灯是否可以直接更换为H7灯泡,并提供了完整的教程下载地址。此外,还详细讲解了DSP功能函数中的数据拷贝、数据填充和浮点数转换为定点数的相关内容。 ... [详细]
  • 本文介绍了win7系统休眠功能无法启动和关闭的解决方法,包括在控制面板中启用休眠功能、设置系统休眠的时间、通过命令行定时休眠、手动进入休眠状态等方法。 ... [详细]
author-avatar
ghost
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有