由于 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 编译器符号名称不匹配而导致无法解析的外部符号的主要内容,如果未能解决你的问题,请参考以下文章
Windows MSVC 符号表(.lib文件)(C++符号表解析)(符号表是如何产生的)(第四步:链接)
spring boot 2.0.0由于版本不匹配导致的NoSuchMethodError问题解析