排查Windows平台动态库和静态库链接失败问题
最近帮同事查了一个C++链接过程的问题,这个问题比较隐蔽,也非常有代表性,记录下来方便后面查阅。
动态库和静态库
在软件开发中,通常将相似或具有关联性的代码归入一个模块中,这个模块会以动态库或静态库的形式独立出来。每个静态库或动态库会作为独立的编译单元生成目标文件,这些目标文件最终会被链接在一起。这些静态库和动态库之间大多具有依赖关系,在链接过程中如果所依赖的函数出现了缺失就会链接失败。
以 __imp_
开头的函数缺失
同事的这个工程在以静态库方式链接时出现以 __imp_
开头的函数缺失,通常情况下报这个问题是因为该函数没有定义。但是,在仔细观察函数的名称后发现该函数已经被定义出来了,这就很奇怪了。
使用dumpbin工具插件动态库的函数
查看与链接相关的函数名称
dumpbin /linkermember xxx.lib
在命令的输出结果中搜索能够找到该函数,但是函数名称前没有 __imp_
前缀。查阅资料后发现 __imp_
前缀是windows平台下动态库导出函数的前缀。
为什么在链接时寻找的是动态库版本的函数呢?这个与函数声明的头文件有关,由于头文件中使用了条件编译来区分动态库和静态库版本,而默认情况下使用动态库导出标识符 dllexport/dllimport
,将静态的宏定义加上后就能链接通过了。
tips:其他实用的dumpbin指令
查看静态库中的函数
dumpbin /symbols xxx.lib
查看动态库中的导出函数
dumpbin /exports xxx.dll
查看动态库的依赖库
dumpbin /dependents xxx.dll