Visual Studio基于vcpkg的C++项目出现LNK2001未解析外部符号(HPDF系列函数)问题求助
Visual Studio基于vcpkg的C++项目出现LNK2001未解析外部符号(HPDF系列函数)问题求助
我正在Visual Studio中搭建一个以C++项目为主的解决方案,全程基于vcpkg技术进行依赖管理。但在构建过程中,其中一个项目总是失败,抛出的链接错误如下:
1>pdfwrap.obj : error LNK2001: unresolved external symbol _HPDF_New 1>pdfwrap.obj : error LNK2001: unresolved external symbol _HPDF_LoadTTFontFromFile 1>pdfwrap.obj : error LNK2001: unresolved external symbol _HPDF_Free
出错的目标文件pdfwrap.obj路径为:
C:\Development\workarea\<Solution>\<Project>\Release\pdfwrap.obj
由于hpdf是通过vcpkg引入的,我在多个路径下找到了对应的.lib和.dll文件,这里列出主要的几个:
C:\Development\workarea\Debug\hpdf.dll C:\Development\workarea\<Solution>\<Project>\vcpkg_installed\x86-windows\x86-windows\bin\hpdf.dll C:\Development\workarea\<Solution>\<Project>\vcpkg_installed\x86-windows\x86-windows\debug\bin\hpdf.dll C:\Development\workarea\<Solution>\<Project>\vcpkg_installed\x86-windows\x86-windows\debug\lib\hpdf.lib C:\Development\workarea\<Solution>\<Project>\vcpkg_installed\x86-windows\x86-windows\lib\hpdf.lib C:\Development\workarea\vcpkg\buildtrees\libharu\x86-windows-dbg\src\hpdf.dll C:\Development\workarea\vcpkg\buildtrees\libharu\x86-windows-dbg\src\hpdf.lib C:\Development\workarea\vcpkg\buildtrees\libharu\x86-windows-rel\src\hpdf.dll C:\Development\workarea\vcpkg\buildtrees\libharu\x86-windows-rel\src\hpdf.lib C:\Development\workarea\vcpkg\packages\libharu_x86-windows\bin\hpdf.dll C:\Development\workarea\vcpkg\packages\libharu_x86-windows\debug\bin\hpdf.dll C:\Development\workarea\vcpkg\packages\libharu_x86-windows\debug\lib\hpdf.lib C:\Development\workarea\vcpkg\packages\libharu_x86-windows\lib\hpdf.lib
我专门针对未解析的HPDF_New符号做了验证:
对.lib文件执行命令:
dumpbin /exports C:\Development\workarea\vcpkg\packages\libharu_x86-windows\lib\hpdf.lib | findstr /WI "HPDF_New" _HPDF_New@8
对.dll文件执行命令:
dumpbin /Exports C:\Development\workarea\vcpkg\packages\libharu_x86-windows\bin\hpdf.dll | findstr /I "HPDF_New" 356 163 00006A60 HPDF_New = _HPDF_New@8
从结果来看符号明明存在,那找不到的原因我猜测可能有两个:
- 会不会是函数名末尾的
@8后缀导致匹配失败? - 或者链接器根本没有在正确的目录下查找?
为了排查问题,我给链接过程开启了详细日志,设置界面如下:
之后得到了额外的构建日志片段:
1> Searching libraries 1> Searching C:\Program Files (x86)\Windows Kits\10\lib\10.0.26100.0\um\x86\UxTheme.lib: 1> Searching C:\Development\workarea\<Solution\>\<Project\>\vcpkg_installed\x86-windows\x86-windows\lib\hpdf.lib: 1> Searching C:\Development\workarea\<Solution\>\<Project\>\vcpkg_installed\x86-windows\x86-windows\lib\libpng16.lib: 1> Searching C:\Development\workarea\<Solution\>\<Project\>\vcpkg_installed\x86-windows\x86-windows\lib\zlib.lib: 1> Searching C:\Development\workarea\Release\<several *.lib files>: 1> Searching C:\Program Files\Microsoft Visual Studio\2022\Professional\VC\Tools\MSVC\14.44.35207\<several *.lib files in subdirectories>: 1> Searching C:\Program Files (x86)\Windows Kits\10\lib\10.0.26100.0\um\x86\<several *.lib files>: 1> Searching C:\Program Files (x86)\Windows Kits\10\lib\10.0.26100.0\ucrt\x86\ucrt.lib: 1> Finished searching libraries 1> pdfwrap.obj : error LNK2001: unresolved external symbol _HPDF_New
而且我也再次确认了链接器搜索的那个hpdf.lib里确实包含目标符号:
dumpbin /exports C:\Development\workarea\<Solution>\<Project>\vcpkg_installed\x86-windows\x86-windows\lib\hpdf.lib | findstr /I "HPDF_New" _HPDF_New@8
对应的dll文件也一样:
dumpbin /exports C:\Development\workarea\<Solution>\<Project>\vcpkg_installed\x86-windows\x86-windows\bin\hpdf.dll | findstr /I "HPDF_New" 356 163 00006A60 HPDF_New = _HPDF_New@8
有没有大佬能帮我分析下,为什么明明符号存在却还是报未解析的错误?我该怎么解决这个问题?
补充排查:32位/64位兼容性
有人提到函数名后的@8后缀可能是因为dll是64位,但我的程序是32位的。不过我用sigcheck工具验证过了:
C:\Development\workarea\<Solution>\<Project>\vcpkg_installed\x86-windows\x86-windows\bin>sigcheck hpdf.dll Sigcheck v2.90 - File version and signature viewer Copyright (C) 2004-2022 Mark Russinovich Sysinternals - www.sysinternals.com C:\Development\workarea\<Solution>\<Project>\vcpkg_installed\x86-windows\x86-windows\bin\hpdf.dll: ... MachineType: 32-bit
所以这个可能性已经排除了。
再补充:调用约定(stdcall/cdecl)的疑问?
我在源码中是这样调用HPDF_New的:
// 自己的cpp文件 HPDF_Doc pdfTempDoc = HPDF_New(nullptr, nullptr);
而vcpkg安装目录里的头文件定义是这样的:
#ifndef HPDF_EXPORT #define HPDF_EXPORT(A) A #endif /* HPDF_EXPORT */ ... #ifdef __cplusplus extern "C" { #endif ... HPDF_EXPORT(HPDF_Doc) HPDF_New (HPDF_Error_Handler user_error_fn, void *user_data);
另外我专门加了代码检测当前编译单元的模式:
#ifdef __cplusplus # error "__cplusplus is defined" #endif #ifndef __cplusplus # error "__cplusplus is not defined" #endif
结果错误列表显示__cplusplus is defined,说明当前是按C++模式编译的:
备注:内容来源于stack exchange,提问作者Dominique




