当我们构建一个程序时,一些符号将在链接时解析(如.lib
中的那些),
但有些可以在运行时解析(.dll
中的那些),
我怀疑编译器是如何知道的,或者我们如何通知编译器?
答案 0 :(得分:3)
链接代码时,编译器会在静态库和动态库中搜索未定义的符号。如果它找到动态库导出的动态符号,则将符号解析延迟到运行时;如果找到静态符号,它会立即解析符号;如果它根本找不到符号,它会报告错误(除非您正在编译共享库,在这种情况下它可以)。
您可以使用nm -D
检查共享库导出的动态符号。
答案 1 :(得分:1)
您必须为编译时的主体不可用的函数声明原型。
您可以通过包含适当的标题(.h
文件)来执行此操作,该标题将包含如下定义:
int foo(int bar);
注意那里没有尸体。
通常,对于共享库,还存在一个间接层,其中形成包含函数指针的结构。加载库时,它会调整函数指针以引用共享库中包含的函数。
答案 2 :(得分:0)
那些可以在链接时解决的是;那些不能在运行时在共享库中搜索的那些。
答案 3 :(得分:0)
链接器完成了这项工作。
动态函数的原始代码可以编译为对函数指针的调用。 [实际上,这是链接器的工作:将函数调用替换为其引用以生成可执行文件]。
答案 4 :(得分:0)
编译器需要在编译时知道函数声明。然后,链接器将在链接时链接到声明以生成可执行文件。
对于动态加载的库,您可以使用dlopen dlsym和dlclose插入代码以在运行时获取符号。现在这些函数调用搜索符号,如果在动态库中找不到它们,则返回错误。因此,您还需要处理此错误。动态库加载不会确保符号已被解析和链接。加载动态库时,它仍然必须存在。
编辑:修正了可怕的语法