由于 VC9 编译器符号名称不匹配而导致无法解析的外部符号

Posted

技术标签:

【中文标题】由于 VC9 编译器符号名称不匹配而导致无法解析的外部符号【英文标题】:Unresolved external symbol due to VC9 compiler symbol name mismatch 【发布时间】:2012-03-28 20:47:46 【问题描述】:

我在尝试链接时看到以下错误消息 一个项目中的库与同一解决方案中的另一个库:

CPTemplate.obj : error LNK2019: unresolved external symbol "public: long __thiscall MPADOFieldList::GetField(wchar_t *,struct Field * *)" (?GetField@MPADOFieldList@@QAEJPA_WPAPAUField@@@Z) referenced in function "public: virtual long __stdcall CCPTemplate::GetRootStorage(struct IMPRootStore * *)" (?GetRootStorage@CCPTemplate@@UAGJPAPAUIMPRootStore@@@Z)

在我要链接的静态库上使用“dumpbin /symbols” 反对为“GetField”方法揭示了一个不同的符号:

?GetField@MPADOFieldList@@QAEJPA_WPAPAUADOField@@@Z (public: long __thiscall MPADOFieldList::GetField(wchar_t *,struct ADOField * *))

显然,区别在于“Field”与“ADOField”。 “字段”已定义 在引用的标题中:

typedef interface ADOField Field;

'GetField'方法的声明如下:

HRESULT GetField( BSTR  bstrFieldName,  Field**  rpField );

【问题讨论】:

库是否使用与二进制文件相同的编译器并使用相同的设置进行编译(尤其是考虑到由于 BSTR 参数而在此处处理字符串)? 相同的编译器,相同的机器,据我所知(来自 Visual Studio 对 cl.exe 的调用),相同的设置。 【参考方案1】:

这几乎可以肯定归结为两件事之一,typedef 是有条件的,对于 lib,它需要一个分支,而在主项目中它需要另一个。但是,由于类型在主项目中解析为Field,我有一个更合理的理论。包含GetField 声明的标头具有Field 的前向声明,但是在此 TU 中根本看不到 typedef,因此假定它是将在其他地方定义的类型(导致第一个链接)。然而,在库中,可以看到 typedef 并正确解析为 ADOField,从而导致不匹配。解决方案是确保在包含 CCPTemplate::GetRootStorage 定义的 TU 中看到 typedef。

【讨论】:

它看起来不是一个前向声明,而是一个不同版本的 ADO 库,它在包含定义 GetField 的标头之前通过单独的标头包含。

以上是关于由于 VC9 编译器符号名称不匹配而导致无法解析的外部符号的主要内容,如果未能解决你的问题,请参考以下文章

由于未解析的符号,使用向导创建的 ATL 项目无法编译

电脑应用程序错误,怎么办?

Windows MSVC 符号表(.lib文件)(C++符号表解析)(符号表是如何产生的)(第四步:链接)

spring boot 2.0.0由于版本不匹配导致的NoSuchMethodError问题解析

spring boot 2.0.0由于版本不匹配导致的NoSuchMethodError问题解析

无法解析的外部符号 LNK错误总结