【问题标题】:Unresolved external symbol even if everything seems OK即使一切正常,外部符号也无法解析
【发布时间】:2022-01-26 05:00:10
【问题描述】:

我不习惯在 Windows 上编码,我对 VS 上的这个错误感到困惑。

我正在开发一个静态库libA,另一个libB 调用libA 中的一些方法,以及一个程序prog 调用libB 中的一些方法。

libA 编译没有任何问题。

libB 也是如此。 libA 的 include 和 lib 文件夹提供给 VS,以及 libA.lib 作为附加依赖项。

对于prog,我给出了关于libAlibB 的include 和lib 文件夹。这两个库本身作为附加依赖项提供。它可以编译,但是在链接时,我遇到了 LNK2001 类型的几个错误:

unresolved external symbol "public virtual void __thiscall libA::classA1::methodA1(void)" (?methodA1@classA1@libA@@UEAXXZ) in File libB.lib(classB1.obj)

我做了一个libB 的dumpbin,符号?methodA1@classA1@libA@@UEAXXZ 在dump 文件中出现了很多次。

Dump of file .\libB.lib

File Type: LIBRARY

Archive member name at 8: /                
61C9303F time/date Mon Dec 27 12:17:19 2021
         uid
         gid
       0 mode   36987E size correct header end

14630 public symbols 

...
3F43C3C ?methodA1@classA1@libA@@UEAXXZ
...

Archive member name at 3698C2: /                
61C9303F time/date Mon Dec 27 12:17:19 2021
         uid
         gid
       0 mode   36272A size correct header end

61 offsets

...
32 ?methodA1@classA1@libA@@UEAXXZ
... 

SECTION HEADER #42 .text$mn name
       0 physical address
       0 virtual address
     1D7 size of raw data
    5FA3 file pointer to raw data (00005FA3 to 00006179)
    617A file pointer to relocation table
       0 file pointer to line numbers
       D number of relocations
       0 number of line numbers 60501020 flags
         Code
         COMDAT; sym= "public: virtual void __cdecl libA::classA1::methodA1(void)" (?methodA1@classA1@libA@@UEAAXXZ)
         16 byte align
         Execute Read

...

SECTION HEADER #92
  .xdata name
       0 physical address
       0 virtual address
      1C size of raw data
    6B4E file pointer to raw data (00006B4E to 00006B69)
    6B6A file pointer to relocation table
       0 file pointer to line numbers
       1 number of relocations
       0 number of line numbers
40301040 flags
         Initialized Data
         COMDAT; sym= $unwind$?methodA1@classA1@libA@@UEAAXXZ
         4 byte align
         Read Only

...

SECTION HEADER #93
  .pdata name
       0 physical address
       0 virtual address
       C size of raw data
    6B74 file pointer to raw data (00006B74 to 00006B7F)
    6B80 file pointer to relocation table
       0 file pointer to line numbers
       3 number of relocations
       0 number of line numbers
40301040 flags
         Initialized Data
         COMDAT; sym= $pdata$?methodA1@classA1@libA@@UEAAXXZ
         4 byte align
         Read Only

...

RELOCATIONS #93
                                                Symbol    Symbol
 Offset    Type              Applied To         Index     Name
 --------  ----------------  -----------------  --------  ------
 00000000  ADDR32NB                   00000000       124  $LN269
 00000004  ADDR32NB                   000001D7       124  $LN269
 00000008  ADDR32NB                   00000000       22A  $unwind$?methodA1@classA1@libA@@UEAAXXZ

...

RELOCATIONS #101
                                                Symbol    Symbol
 Offset    Type              Applied To         Index     Name
 --------  ----------------  -----------------  --------  ------
 00000000  ADDR64            00000000 00000000       3BA  ??_R4classA1@libA@@6B@ (const libA::classA1::`RTTI Complete Object Locator')
 00000008  ADDR64            00000000 00000000        D3  ??_EclassA1@libA@@UEAAPEAXI@Z (public: virtual void * __cdecl libA::classA1::`vector deleting destructor'(unsigned int))
 00000010  ADDR64            00000000 00000000        8D  _purecall
 00000018  ADDR64            00000000 00000000        8D  _purecall
 00000020  ADDR64            00000000 00000000        CE  ?methodA1@classA1@libA@@UEAAXXZ (public: virtual void __cdecl libA::classA1::methodA1(void))
 00000028  ADDR64            00000000 00000000        CF  ?methodA2@classA1@libA@@UEAAXXZ (public: virtual void __cdecl libA::classA1::methodA2(void))

...

0CE 00000000 SECT42 notype ()    External     | ?methodA1@classA1@libA@@UEAAXXZ (public: virtual void __cdecl libA::classA1::methodA1(void))

...

22A 00000000 SECT92 notype       Static       | $unwind$?methodA1@classA1@libA@@UEAAXXZ
22B 00000000 SECT93 notype       Static       | .pdata
    Section length    C, #relocs    3, #linenums    0, checksum AAAF74B1, selection    5 (pick associative Section 0x42)
22D 00000000 SECT93 notype       Static       | $pdata$?methodA1@classA1@libA@@UEAAXXZ
22E 00000000 SECT94 notype       Static       | .voltbl
    Section length    4, #relocs    0, #linenums    0, checksum D5442740, selection    5 (pick associative Section 0x42)

libA 的 dumplib 文件也是如此。

如果有帮助,这里是prog 的链接器命令:

/OUT:"C:\prog\Release\prog.exe" /MANIFEST /LTCG:incremental /NXCOMPAT /PDB:"C:\prog\Release\prog.pdb" /DYNAMICBASE "libA.lib" "libB.lib" "some_other_libs.lib" /DEBUG /MACHINE:X86 /OPT:REF /SAFESEH /INCREMENTAL:NO /PGD:"C:\prog\Release\prog.pgd" /SUBSYSTEM:CONSOLE /MANIFESTUAC:"level='asInvoker' uiAccess='false'" /ManifestFile:"Release\prog.exe.intermediate.manifest" /LTCGOUT:"Release\prog.iobj" /OPT:ICF /ERRORREPORT:PROMPT /ILK:"Release\prog.ilk" /NOLOGO /TLBID:1

【问题讨论】:

  • 显然,libA::classA1::methodA1 并没有在这两个库中实际实现。
  • @IgorTandetnik 确实来自libA 的一些方法是纯虚方法,但它们在libB 中实现(libA 实际上是一个框架)。此外,libA 的非纯虚方法也有此错误,默认情况下在libA 中实现。
  • 尝试在命令行切换libA.lib和libB.lib的顺序。
  • @n.1.8e9-where's-my-sharem。我不相信这会解决问题。我换了他们的订单以防万一,但这并没有改变问题。不过还是谢谢。
  • “多次出现”。我建议也将它们发布在这里。对于 libA 和 libB。

标签: c++ visual-studio linker static-libraries


【解决方案1】:

终于找到问题所在了。

libA 和 libB 在 Linux 上正常工作,所以我不明白为什么在 Windows 上会出现这个问题。

事实证明,我真的不知道为什么,但是 CMake 生成的 VS 解决方案文件允许使用 x86 目标架构编译 libA,但在命令行部分(项目属性 > 链接器(或静态库的库管理器)> 命令行)。

我删除了这个“/machine x64”选项,重新编译了libA,现在整个东西编译和链接了。

【讨论】:

  • 您好,很高兴知道您找到了解决此问题的解决方案!请考虑回答并接受它作为将其状态更改为已回答的答案。见can I answer my own question..,只是一个提醒:)
猜你喜欢
  • 1970-01-01
  • 2019-03-15
  • 1970-01-01
  • 2013-07-23
  • 2021-06-30
  • 2018-07-01
  • 2018-01-16
  • 2018-02-21
  • 1970-01-01
相关资源
最近更新 更多