在静态库项目中,我有一个头文件,其中包含已声明但未实现的函数。
我有一个实现这些功能的 .cpp 文件。
然后,为了更好地理解链接器错误,我复制了 cpp 文件,所以我有一个完全相同的拷贝,它也被编译了。因此,这两个文件的标题中的每个符号都有双重实现。
它编译,当在另一个项目中使用时,它链接。
这里是静态库的最小示例:
API.hpp:
void printWhatever();
errortest.cpp 和 duplicate.cpp 是相同的:
#include "api.hpp"
#include <iostream>
void printWhatever(){
std::cout << "hi " << "\n";
}
我用这两个源文件将其编译为静态库。我看到编译器为这两个文件生成报告。
现在我在一个可执行文件中使用这个编译库,一个不同的项目: main.cpp :
#include <api.hpp>
int main(int argc, const char * argv[]) {
printWhatever();
return 0;
}
它运行并打印“hi”。
为什么函数没有多重定义?
最佳答案
添加到这个问题的关键事实是,具有重复符号的两个模块被链接到一个静态库。
静态库与共享库的工作方式截然不同。链接时,链接器在静态库中搜索引用的符号。定义引用符号的第一个模块被链接以生成最终的可执行文件。另一个模块定义相同符号的事实无关紧要。如果具有重复符号的其他模块未定义可执行文件所需的任何其他符号,则它不会链接到可执行文件中。
如果您想看到静态库的重复错误:
从 main()
调用 foo()
和 bar()
。
在静态库的第一个模块中定义foo()
和baz()
。
在静态库的第二个模块中定义bar()
和baz()
。
因为两个模块都包含从 main()
引用的符号,它们被迫与可执行文件链接,导致 baz()
出现重复符号错误。
关于c++ - 为什么不在这个静态库中创建多个已定义的符号?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37860582/