我该如何理解并解决未解析的外部符号错误?

编程语言 2026-07-12

我正在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

依我之见,这意味着他正在查找的引用确实存在,因此如果找不到,可能意味着以下几种情况:

  1. 要么他无论如何都找不到它(因为名称末尾的 @8?)
  2. 要么他没有在正确的目录中查找。

为了确定问题出在哪里,我决定在链接过程中增加一些详细日志输出:

在此输入图片描述

这导致构建日志中出现以下额外日志:

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

虽然:

dumpbin /exports C:\Development\workarea\<Solution>\<Project>\vcpkg_installed\x86-windows\x86-windows\lib\hpdf.lib | findstr /I "HPDF_New"
                  _HPDF_New@8

...以及:

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

编辑:stdcallcdecl 之间的区别?

在源代码中,函数 _HPDF_New() 的调用如下:

<own_cpp_file>
HPDF_Doc    pdfTempDoc = HPDF_New(nullptr, nullptr);

<header_file_inside_vcpkg_installed_directory>:
#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);

__cplusplus 的定义而言:我添加了以下代码行:

#ifdef __cplusplus
#  error "__cplusplus is defined"
#endif

#ifndef __cplusplus
#  error "__cplusplus is not defined"
#endif

在错误列表中,我看到了如下内容: 错误列表截图

解决方案

被导出为 _HPDF_New@8 的DLL函数很可能使用STDCALL调用约定。但是你的项目尝试以 _HPDF_New 导入该函数,很可能意味着它认为该函数使用CDECL调用约定。调用约定不匹配可能导致链接错误。因此,请仔细检查你的项目代码中是否存在调用约定不匹配的问题。如果你在代码中手动声明了该函数,请确保声明正确。如果你从随DLL提供的头文件获得函数声明,请确保定义了任何需要的条件编译以正确配置它。

提问者的说明:
调用约定在代码中的定义如下:

#ifdef HPDF_DLL
#    define HPDF_SHARED
#    define HPDF_EXPORT(A)  __declspec(dllimport) A  __stdcall

正如你所看到的,当 HPDF_DLL 已知时,调用约定是正确的。另一种情况下,调用约定如下:

#ifndef HPDF_EXPORT
#define HPDF_EXPORT(A) extern A

通过将 HPDF_DLL 添加到预处理器包含列表中,问题得到解决:

解决方案截图:项目属性页

站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。

相关文章