32位转64位DLL时链接器无法解析fmt::v9::detail::assert_fail()的原因?
结合你遇到的fmt库版本不匹配、JSON库同类问题,以下是最可能的几个原因:
头文件与链接库版本完全不匹配
你的代码引用的是fmt v9的头文件(从符号里的fmt::v9可以看出),但实际编译链接的是fmt v11的库。像fmt这类语义化版本的C++库,会把版本号嵌入命名空间来避免跨版本冲突,不同版本的符号命名完全不同,链接器自然找不到对应实现。JSON库的问题大概率也是同理——代码里用的旧版本头文件,却链接了新版本的库。编译模式与库的模式不匹配
链接器搜索fmtd.lib(Debug版库文件),说明你的DLL是Debug模式编译,但如果你用CMake编译fmt时默认生成了Release版的fmt.lib,就会出现找不到Debug库的情况。另外,运行时库选项(MT/MD/MTd/MDd)、字符集设置(多字节/Unicode)如果和fmt库的编译配置不一致,也会引发符号链接失败,甚至间接导致版本相关的符号误解。Jam编译脚本的依赖配置未更新
你的项目用Jam编译,可能脚本里的fmt库路径还是指向旧的32位v9库位置,或者没有正确切换到64位v11库的路径;也可能脚本里指定的库文件名错误(比如仍写fmt.lib,但系统中同时存在v9和v11的同名库,链接器优先选择了旧版本)。这种情况下,即使你编译了新库,链接阶段还是会找错文件。全局安装的旧库干扰
如果系统之前全局安装过fmt v9(比如通过包管理器、全局编译部署),Jam编译时可能优先链接了全局的32位v9库,而64位链接器无法解析32位库的符号,导致未解析错误。或者你编译v11库时没有指定独立的安装路径,导致链接器仍然找到旧版本的库文件。CMake编译fmt时的配置失误
用CMake编译fmt时,可能没有明确指定目标架构为x64,导致生成的还是32位库,64位DLL链接32位库必然失败;另外,如果编译时开启了FMT_HEADER_ONLY选项,fmt会被编译成头文件库,此时不需要链接静态库,但你的代码仍然尝试链接fmt.lib,也会出现符号找不到的问题。
内容的提问来源于stack exchange,提问作者G. Tabs

