编译过程

有人能解释一下编译是如何工作的吗?

我似乎无法弄清编译是如何工作的。

更具体地说,以下是一个例子。我正在尝试在MSVC ++ 6中编写一些代码来加载Lua状态。

我已经完成了以下工作:

  • 将库和包含文件的附加目录设置为正确的目录。
  • 使用了 extern "C"(因为Lua仅为C或者我所听到的)。
  • #include了正确的头文件。

但是我仍然在MSVC++6中遇到一些有关未解析的外部符号的错误(用于我使用的Lua函数)。

尽管我很想知道如何解决这个问题并继续前进,但是我认为如果我能够了解所涉及的基本过程,那么这会更好。是否有人可以为此编写一个良好的解释?我想了解的是这个过程。。它可能是这个样子的:

步骤1:

  • 输入:源代码
  • 处理:解析(在此添加更多详细信息)
  • 输出:在此输出什么。。

步骤2:

  • 输入:从步骤1输出的任何内容,加上可能需要的任何其他内容(库?DLL?.so?.lib?)
  • 处理:对输入执行的任何处理
  • 输出:输出什么

以此类推。

谢谢。。

也许这将解释符号是什么,何为“链接”,什么是“目标”代码等。

谢谢。。对于我是这样的新手感到抱歉。。

P.S. 不必具体限定语言。但是请随意使用您最舒适的语言来表达。 :)

编辑:无论如何,我成功解决了错误,结果发现我必须手动将.lib文件添加到项目中。在IDE设置或项目设置中指定库目录(.lib所在的位置)是不起作用的。

但是,以下答案在某种程度上帮助我更好地理解了该过程。非常感谢!如果有人仍然想编写全面的指南,请这样做。:)

编辑:为了更多的参考资料,我找到了一位作者Mike Diehl的两篇文章,解释得很好。 :) Examining the Compilation Process: Part 1 Examining the Compilation Process: Part 2

原文链接 https://stackoverflow.com/questions/510309

点赞
stackoverflow用户6258
stackoverflow用户6258

将LUA库添加到项目设置中

你需要进入项目设置并添加一个目录,其中你有一个LUA库*.lib文件,该文件位于“链接器”选项卡中的“包含库”或类似名称的设置中,很抱歉我无法查找到具体名称。

之所以会出现“未解决的外部符号”是因为C++编译分为两个阶段。首先,代码会被编译成单独的.obj文件,每个.cpp文件对应一个.obj文件,然后“链接器”会将所有的.obj文件组合成一个.exe的可执行文件。.lib文件就是一堆.obj文件合并在一起,以使库的发布变得更加简单。

因此,通过添加所有的“#include”和extern声明,你告诉编译器,代码中存在这些签名,但链接器无法找到这些代码,因为它不知道实际代码存在的.lib文件的位置。

确保你已经阅读了库的REDME文件,通常它们会详细解释如何将库包含在您的代码中。

2009-02-04 07:00:01
stackoverflow用户49942
stackoverflow用户49942

编译器步骤:

  • 输入:源代码文件

  • 处理:解析源代码并将其翻译成机器码

  • 输出:目标文件,包含以下内容:

    • 在此目标文件中定义并导出的符号名称
    • 与在此目标文件中定义的每个符号所关联的机器码
    • 此目标文件未定义的符号名称,但此目标文件中的软件依赖于它们,并且必须随后链接到它们,即此目标文件导入的名称

链接步骤:

  • 输入:

    • 第 1 步中的目标文件
    • 其他对象的库(例如来自操作系统和其他软件的库)
  • 处理:

    • 对于要链接的每个对象
    • 获取该对象导入的符号列表
    • 在其他库中查找这些符号
    • 将相应的库链接到您的目标文件
  • 输出:包含来自所有对象的机器码以及已链接到您的对象的库对象的单个可执行文件。

2009-02-04 07:10:50
stackoverflow用户11215
stackoverflow用户11215

编译和链接

主要步骤分为编译和链接。

编译需要单个编译单元(简单的说就是包含所有头文件的源文件),并创建目标文件。目标文件中有很多函数(以及其他的东西,比如静态数据),这些函数在特定的位置(地址)被定义。在下一步链接中,还需要一些关于这些函数的附加信息:名称。因此,它们也被存储。一个目标文件可以引用其它目标文件中的函数(因为它在运行时想要调用它们),但由于我们只处理一个目标文件,因此只有对这些函数的象征性引用(它们的“名称”)存储在目标文件中。

接下来是链接(我们在此只讨论静态链接)。链接是将在第一步中创建的目标文件(直接创建,或在组合在一个.lib文件中之后)一起进行,并创建一个可执行文件。

在链接步骤中,将一个目标文件或lib到另一个目标文件或lib的所有象征性引用(如果可以)解析出来,在正确的对象中查找名称,找到函数的地址,并将地址放在正确的位置上。

现在,为了解释一些“extern“C”的事情,你需要知道:

C没有函数重载。函数总是通过它的名称来识别。因此,当编译代码作为C代码时,只有函数的真实名称存储在目标文件中。

但是C++有一些称为“函数/方法重载”的东西。这意味着函数的名称不再足以标识它。因此,C++编译器会为函数创建包括函数原型的名称(因为名称加上原型将唯一标识一个函数)。这被称为名称重整。

当你想在C++项目中使用以“C”代码编译的库时,你需要“extern“C””指定。

对于你的确切问题:如果它仍然不起作用,这些提示可能会有所帮助:

 * Lua二进制文件是否使用相同版本的VC++编译?  * 你能否在你的VC解决方案中,或者作为C ++代码的单独项目中自己编译Lua?  * 你确定你所有的‘外部“C”’都是正确的吗?

2009-02-04 07:16:31
stackoverflow用户78244
stackoverflow用户78244
2009-06-08 20:45:26