C/C++从源码到可执行程序的过程

2023-10-29

      C/C++源码生成平台下的可执行文件,需要经过3个步骤:预处理、编译、链接。

1.    预处理

将宏、条件编译指令、头文件包含等指令进行展开。也就是说,这是一个代码替换的工作。

C/C++源码经预处理后,不再存在各种宏指令。但展开后依然是代码的形式,是人可读的。

2.    编译

将C/C++代码翻译成汇编代码,然后翻译成平台的机器代码。最终会生成一个与cpp文件同名的目标文件,其后缀名为.o或者.obj。目标文件以二进制形式存在。

通常一个目标文件有两个段:

①   代码段

②   数据段

这一步工作量最大,也是最耗费时间的一步。

3.    链接

将3中生成的目标文件与各种所需的库文件进行链接,生成平台可执行文件。

链接器除了将目标文件与库文件进行链接,还负责未解决符号的链接。未解决符号指extern等关键字修饰的符号。

     

      链接分为两种:

①   内部链接:若一个名称(变量或者函数)对于它的编译单元(cpp)来说是局部的,且在链接时不与其他编译单元相同的名称冲突,那么该名称有内部链接。

②   外部链接:若一个名称(变量或者函数)在链接时可以与其他编译单元(cpp)交互,那么该名称具有外部链接。

 

      由上可知,由于.h文件会被多个编译单元(即.cpp)包含,若.h中有定义,那么每个包含这个.h文件的编译单元都会对同一个符号进行定义,若该符号为外部链接,那么该定义为所有编译单元可见,从而会导致duplicatedexternal symbols链接错误(注意这是个链接错误)。故若头文件中要进行定义,那么必须保证定义的符号只有内部链接。

 

 

C++特点:

      对于C++而言,一个编译单元指一个.cpp文件和它所include的所有.h文件。     预处理时,.h中的代码会替换#include指令,从而扩充到.cpp中。

      然后编译器编译该.cpp文件,生成一个.obj文件,这就是二进制的目标文件。   

      当编译器将所有.cpp都编译完成后,链接器将目标文件与库文件进行链接,生成一个.exe文件或者库文件。

 

 

VisualStudio的工作:

VisualStudio是一个开发工具集,对于C/C++程序而言,它集成了编译器和链接器。

1.    VisualStudio读取配置,确定标准函数库与头文件。包括环境变量中的路径。

2.    VisualStudio确定源代码之间的依赖关系。

所谓依赖关系,是指B文件引用了A文件,那么就必须先编译A,再编译B。故根据依赖关系,编译器必须满足:

①   只有A编译完成后,B的编译才可以开始

②   当A变化后,B会被重新编译

实际上,编译顺序被保存在configure脚本所生成的makefile文件中。这就是为什么编译时要先运行configure。

可知,确定编译顺序的同时,编译所用到的头文件也确定了。

3.    VisualStudio进行预编译头文件的编译

4.    VisualStudio进行预处理,替换掉各种宏命令

5.    VisualStudio进行编译,将源码转换为汇编代码,然后转换为目标代码(机器码)

6.    VisualStudio进行链接。若为静态链接,将函数库复制到可执行文件目录下;若为动态链接,则只在运行时动态调用。

注意静态链接复制函数库这样的操作需要人为进行,VisualStudio无法自动进行。

这就是为什么需要人为复制库文件到生成的可执行目录下。而且程序的清理等操作也不会影响到可执行目录下的这些库文件。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C/C++从源码到可执行程序的过程 的相关文章

  • 如何使用 ASP.NET MVC 进行 HTTP 调用?

    我正在尝试做的事情 我试图练习进行 HTTP 调用 如果这就是它的名字 来自一个简单的 ASP NET MVC Web 应用程序 为此 我尝试从以下位置获取天气详细信息打开天气地图 http openweathermap org appid
  • 为什么在 C# 中成员初始值设定项中不允许这样做,但在 VB.Net Me 中允许

    我正在将 VB Net 应用程序转换为 C 并注意到在 VB Net 代码中 有一个私有成员变量 它是使用Me像这样 Private m ClassA As New MyCollection Of ClassA Me 当我将其转换为 C 代
  • 用 C# 启动 Windows 服务

    我想启动一个刚刚安装的Windows服务 ServiceBase ServicesToRun if bool Parse System Configuration ConfigurationManager AppSettings RunSe
  • C++ 模板中的名称查找

    我有一些 C 代码 如果没有 fpermissive 选项 就无法再编译 这是我无法分享的专有代码 但我认为我已经能够提取一个简单的测试用例来演示该问题 这是 g 的输出 template eg cpp In instantiation o
  • OpenCV Visual Studio ntdll.dll

    我尝试在 Visual Studio 2013 上使用 OpenCV 2 4 10 创建一个项目 但由于以下异常 到目前为止我运气不佳 请建议帮助 TIA letstryitonemoretime exe Win32 Loaded C Us
  • asp.net c# 将数据集中的数据转换为电子邮件正文?

    从数据集到电子邮件正文的最佳方式是什么 我有一个 net 控制台应用程序 用于根据存储过程的结果发送电子邮件通知 并且想知道如何最好地从 SQL 数据转到电子邮件正文 带有颜色和字体的 html 正文是最好的 但纯文本也可以 thanks
  • C 中的复合语句表达式

    下面的代码不起作用 int i void 999 100 添加括号就可以了 为什么 int i void 999 100 还有另一种方法可以完成此类分配 int i void 999 100 是什么让他们与众不同 在这份声明中 int i
  • C++ 中的单例和抽象基类

    最近我遇到了关于实现 Singleton 但涉及抽象基类的问题 假设我们有这样的类层次结构 class IFoo it s ABC class Foo public IFoo 我们的单例类定义如下 template
  • 返回指向 std::vector 中的对象的 a

    我有一个关于返回对向量元素的引用的非常基本的问题 有一个向量vec存储类的实例Foo 我想访问这个向量中的一个元素 不想使用向量索引 我应该如何编码该方法getFoo here include
  • 如何在 C++ 中对静态缓冲区执行字符串格式化?

    我正在处理一段对性能要求非常高的代码 我需要执行一些格式化的字符串操作 但我试图避免内存分配 甚至是内部库的内存分配 在过去 我会做类似以下的事情 假设是 C 11 constexpr int BUFFER SIZE 200 char bu
  • 使用成员作为实现者来实现接口

    我有实现 IA 的 A 类 现在我需要创建也应该实现 IA 的类 B B 类有 A 类的实例作为成员 有什么方法可以定义A的实例实现B类中的IA吗 interfase IA void method1 void method2 void me
  • 替换 JSON 中的转义字符

    我想用空格替换 JSON 字符串中的 字符 我怎样才能做到这一点 我发现从 JSON 字符串中删除所有转义字符的最简单 最好的方法是将字符串传递到正则表达式 Unescape 方法 此方法返回一个没有转义字符的新字符串 甚至删除了 n t
  • 获取给定EntityType的导航属性

    我在用VS2010 EF4 0 需要如下功能 private string GetNaviProps Type entityType eg typeof Employee NorthwindEntities en new Northwind
  • 从窗口内容截取屏幕截图(无边框)

    我正在寻找有关如何使用 C 将表单内容保存在位图中的解决方案 我已经尝试过使用 DrawToBitmap 但它捕获了所有带边框的窗口 这就是这段代码的结果 public static Bitmap TakeDialogScreenshot
  • 套接字:监听积压并接受

    listen sock backlog 在我看来 参数backlog限制连接数量 这是我的测试代码 server initialize the sockaddr of server server sin family AF INET ser
  • 简单的文档管理系统和API [关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • 如何使用简历实现一个“一网打尽”的异常处理程序?

    我想知道我怎样才能写一个抓住他们全部应用程序级别的异常处理程序将为用户提供恢复应用程序流程的选项 如果您正在运行 Windows 窗体应用程序 将处理程序添加到Application ThreadException event
  • 在代码中而不是 XAML 中呈现 UserControl

    我想用RenderTargetBitmap将 UserControl 呈现为位图 而无需为其编写 XAML 当我这样做时 我得到一张空白图像 我是否错过了关键的一步 ValTool Controls VideoFisheyeOverlayC
  • 什么时候使用静态库需要头文件?

    如果我在 Linux 中用 C 创建一个静态库并生成 a 文件 我 或其他人 如何使用该库 例如 我的库定义了一个类 我认为仅仅提供 a 文件是不够的 还需要提供头文件 我如何知道 a 文件必须提供哪些头文件 例如 我是否需要提供我的库代码
  • 如何将 char 转换为 unsigned int?

    我有一个字符数组 它实际上用作字节数组 而不是用于存储文本 在数组中 有两个特定字节表示我需要存储到无符号 int 值中的数值 下面的代码解释了设置 char bytes bytes 2 bytes 0 0x0C For the sake

随机推荐