发布时间:2023-11-20 16:30
在我们封装底层库的时候,有时会想能不能把底层的库直接打包进我们的库里,之前也一直有这样的疑问,最近终于把这个问题搞清楚了,如下:
编译静态库时只有编译过程,没有链接过程,静态库引用其它库并不会在编译的时候把引用的库函数编译到生成的 lib 中,只是简单的将编译后的中间文件打包,在编译最终的可执行项目(.exe 和 .dll)的时候,需要引用所有的库,进行符号消解。如果你需要封装,使用动态库。
在使用库的时候,经常会遇到如下问题:
1. 出现无法定义的符号错误
这表明链接阶段找不到函数的定义,在dependlib.lib中没有导出你需要的函数;最简单的测试方法是将dependlib做成动态链接库,用depends查看导出的函数。我怀疑是在导出函数时没有加上 extern “C” 标记,由于C++符号表的原因导出函数不是原函数
2. 同时引用depend1.lib和depend2.lib
因为depend1.lib在编译阶段已经将depend2.lib所有函数编译到静态库的地址空间,因此原来在depend2.lib库中的所有函数在depend1.lib库中都有一份定义,在调用其中任何一个库里的函数时,链接阶段都会出现函数重复定义的编译错误
那是不是我们就没有办法将底层库打包呢?答案还是有的,如下:
唯一的方法是使用librarian / archiver工具(例如Linux上的ar)通过链接多个库来创建一个新的静态库。
在Linux或MingW上,使用GNU工具链:
ar -M <
如果你不删除liba.a
和libb.a
,你可以做一个“瘦档案”:
ar crsT libab.a liba.a libb.a
在Windows上,使用MSVC工具链:
lib.exe /OUT:libab.lib liba.lib libb.lib