繁体   English   中英

函数调用者如何使用头文件来确定如何处理已编译的二进制文件?

[英]How does a function caller use a header file to determine what to do with a compiled binary?

我的理解是C ++(我猜是C)头文件从不编译,而只是充当它们描述的C ++文件接口的解释。

因此,如果我的头文件描述了hello()函数,则包含头文件的某些程序将了解hello()以及如何调用它以及为其提供哪些参数等。

但是,在编译之后(并且在链接之前,我猜不确定吗?我不确定),当hello.c文件是二进制机器代码,而hello.h仍然是C ++时,编译器/链接器如何知道如何调用函数在二进制blob中基于其在头文件中的声明的存在?

我了解符号表,抽象语法树等概念(例如,我过去使用过编译器类),但这在我的知识上还是有差距的。

hello()的实现假定了某种调用约定(堆栈上的参数在哪里,谁清除了调用者或被调用者的堆栈,等等)。

编译器将使用正确的调用约定生成代码。 它可以使用头文件中的信息来执行此操作(例如,该函数在Windows程序中标记为__stdcall),也可以使用其默认的调用约定。 编译器还将使用头文件来确保您使用正确数量和参数类型来调用例程。 编译器生成代码后,便不再使用头文件。

链接器与调用约定无关,它的主要职责是通过修复模块及其调用的任何库之间的引用,将已编译的二进制文件修补在一起。

AC / C ++编译单元(cpp文件/ c文件)包括所有头文件(作为文本)和代码。

头文件有助于说明如何产生调用指令

 push arg1
 push arg2
 call _some_function

如果编译单元包含_some_function那么它将在编译时解决。

否则,它将成为未定义的符号 如果是这样,当链接程序出现时,它将遍历所有目标文件和库以解析所有未定义的符号

  • 因此,头文件可帮助正确编码程序集。
  • 对象和库文件提供了实现。

库文件是可选的。 当链接器在库文件中查找时,只有在满足某些符号的情况下才会添加链接器,否则不会将其添加到二进制文件中。

目标文件(忽略优化)将完全添加到二进制文件中。

构建C ++程序分两步:编译和链接。 标头用于编译您正在编写的模块。 二进制文件用于链接:它包含相应报头中定义的方法的已编译代码。 标头必须匹配已编译的内容。 在链接时,您将了解标头是否具有与二进制文件中编译的方法签名匹配的方法签名。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM