关于C编译器的内部逻辑

时间:2010-07-15 01:41:52

标签: c compiler-construction build-process

当我们构建一个程序时,一些符号将在链接时解析(如.lib中的那些),

但有些可以在运行时解析(.dll中的那些),

我怀疑编译器是如何知道的,或者我们如何通知编译器?

5 个答案:

答案 0 :(得分:3)

链接代码时,编译器会在静态库和动态库中搜索未定义的符号。如果它找到动态库导出的动态符号,则将符号解析延迟到运行时;如果找到静态符号,它会立即解析符号;如果它根本找不到符号,它会报告错误(除非您正在编译共享库,在这种情况下它可以)。

您可以使用nm -D检查共享库导出的动态符号。

答案 1 :(得分:1)

您必须为编译时的主体不可用的函数声明原型

您可以通过包含适当的标题(.h文件)来执行此操作,该标题将包含如下定义:

int foo(int bar);

注意那里没有尸体。

通常,对于共享库,还存在一个间接层,其中形成包含函数指针的结构。加载库时,它会调整函数指针以引用共享库中包含的函数。

答案 2 :(得分:0)

那些可以在链接时解决的是;那些不能在运行时在共享库中搜索的那些。

答案 3 :(得分:0)

链接器完成了这项工作。

  • 对于静态函数,链接器将库包含在您的excutable中。呼叫是固定在内存中的位置。
  • 对于动态库,链接器为库提供运行时“搜索器”。动态库发布函数列表及其相对内存地址。因此,运行时可以填充函数指针列表。

动态函数的原始代码可以编译为对函数指针的调用。 [实际上,这是链接器的工作:将函数调用替换为其引用以生成可执行文件]。

答案 4 :(得分:0)

编译器需要在编译时知道函数声明。然后,链接器将在链接时链接到声明以生成可执行文件。

对于动态加载的库,您可以使用dlopen dlsym和dlclose插入代码以在运行时获取符号。现在这些函数调用搜索符号,如果在动态库中找不到它们,则返回错误。因此,您还需要处理此错误。动态库加载不会确保符号已被解析和链接。加载动态库时,它仍然必须存在。

编辑:修正了可怕的语法