You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

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

火山引擎 最新活动