简体   繁体   English

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

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

My understanding is that C++ (and C, I guess) header files are never compiled, and simply act as an explanation of the interface of the C++ file they describe. 我的理解是C ++(我猜是C)头文件从不编译,而只是充当它们描述的C ++文件接口的解释。

So if my header file describes a hello() function, some program that includes the header will know about hello() and how to call it and what arguments to give it, etc. 因此,如果我的头文件描述了hello()函数,则包含头文件的某些程序将了解hello()以及如何调用它以及为其提供哪些参数等。

However, after compilation (and before linking, I guess? I'm not sure), when the hello.c file is binary machine code, and hello.h is still C++, how does the compiler/linker know how to call a function in the binary blob based on the presence of its declaration in the header file? 但是,在编译之后(并且在链接之前,我猜不确定吗?我不确定),当hello.c文件是二进制机器代码,而hello.h仍然是C ++时,编译器/链接器如何知道如何调用函数在二进制blob中基于其在头文件中的声明的存在?

I understand concepts such as symbol tables, abstract syntax trees, etc (ie, I have taken a compiler class in the past), but this is a gap in my knowledge). 我了解符号表,抽象语法树等概念(例如,我过去使用过编译器类),但这在我的知识上还是有差距的。

The implementation of hello() assumes a certain calling convention (where are the parameters on the stack, who cleans up the stack the caller or the callee, etc). hello()的实现假定了某种调用约定(堆栈上的参数在哪里,谁清除了调用者或被调用者的堆栈,等等)。

The compiler generates code with the correct calling convention. 编译器将使用正确的调用约定生成代码。 It may use information from the header file to do this (eg the function is marked __stdcall in Windows program) or it may use it's default calling convention. 它可以使用头文件中的信息来执行此操作(例如,该函数在Windows程序中标记为__stdcall),也可以使用其默认的调用约定。 The compiler will also use the header file to make sure your are calling the routine with the right number and types of parameters. 编译器还将使用头文件来确保您使用正确数量和参数类型来调用例程。 Once the code is generated by the compiler the header file is not used again. 编译器生成代码后,便不再使用头文件。

The linker is not concerned with calling convention it's primary responsibility is to patch together the binaries you've compiled by fixing up references among your modules and any libraries it calls. 链接器与调用约定无关,它的主要职责是通过修复模块及其调用的任何库之间的引用,将已编译的二进制文件修补在一起。

AC/C++ compilation unit (cpp file / c file) includes all the header files (as text) and the code. AC / C ++编译单元(cpp文件/ c文件)包括所有头文件(作为文本)和代码。

The header file helps explain how to produce the call instruction 头文件有助于说明如何产生调用指令

 push arg1
 push arg2
 call _some_function

If the compilation unit includes _some_function then this will be resolved at compile time. 如果编译单元包含_some_function那么它将在编译时解决。

Otherwise it becomes an undefined symbol . 否则,它将成为未定义的符号 If so, when the linker comes along, it looks through all the object files and libraries to resolve all the undefined symbols . 如果是这样,当链接程序出现时,它将遍历所有目标文件和库以解析所有未定义的符号

  • So the header file helps code the assembly correctly. 因此,头文件可帮助正确编码程序集。
  • Object and library files provide implementations. 对象和库文件提供了实现。

The library files are optional. 库文件是可选的。 When a linker looks in a library file, it only gets added if it satisfies some symbol, otherwise it is not added to the binary. 当链接器在库文件中查找时,只有在满足某些符号的情况下才会添加链接器,否则不会将其添加到二进制文件中。

Object files (ignoring optimization) will get added to the binary completely. 目标文件(忽略优化)将完全添加到二进制文件中。

Building a C++ program is a two-step process: compile and link. 构建C ++程序分两步:编译和链接。 The header is for compilation of the module you are writing. 标头用于编译您正在编写的模块。 The binary is for linking: it contains the compiled code for the method defined in the correspnding header. 二进制文件用于链接:它包含相应报头中定义的方法的已编译代码。 The header has to match what's already been compiled. 标头必须匹配已编译的内容。 At link time you will learn if your header has a method signature that matches what was compiled in the binary. 在链接时,您将了解标头是否具有与二进制文件中编译的方法签名匹配的方法签名。

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

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