由于使用 MFC 时"__cdecl"和"__thiscall"调用约定不匹配而导致的链接器错误?

Linker error due to "__cdecl" and "__thiscall" Calling convention mismatch when using MFC?

本文关键字:链接 不匹配 错误 调用 MFC 于使用 cdecl thiscall 约定      更新时间:2023-10-16

我使用的是Visual Studio 2008。我在构建一个项目时遇到了一个链接器错误,该项目只在使用MFC CString(vs std::wstring)时才包含静态链接库。

所以这是有效的:

//header
class FileProcessor
{
    public:
        class iterator;
        friend class iterator;
    //...
    class iterator : public std::iterator<std::input_iterator_tag, std::vector<std::vector<std::wstring>>>
    {
    public:
    //...
    std::vector<std::vector<std::wstring>> operator*() const; 
    }
} 

//cpp 
std::vector<std::vector<std::wstring>> FileProcessor::iterator::operator*() const
{
    return _outerRef->_pimpl->_saxHandler->GetCurrentTable();
}       

但是这个

//header
#include <afx.h>
class FileProcessor
{
    public:
    class iterator;
    friend class iterator;
    //...
    class iterator : public std::iterator<std::input_iterator_tag, std::vector<std::vector<CString>>>
    {
    public:
        //...
        std::vector<std::vector<CString>> operator*() const; 
    }
} 

//cpp 
std::vector<std::vector<CString>> FileProcessor::iterator::operator*() const
{
    return _outerRef->_pimpl->_saxHandler->GetCurrentTable();
}

给出链接器错误:

FileProcessingTests.obj : error LNK2019: unresolved external symbol "public: class
std::vector<class std::vector<class std::basic_string<wchar_t,struct 
std::char_traits<wchar_t>,class std::allocator<wchar_t> >,class std::allocator<class 
std::basic_string<wchar_t,struct std::char_traits<wchar_t>,class 
std::allocator<wchar_t> > > >,class std::allocator<class std::vector<class 
std::basic_string<wchar_t,struct std::char_traits<wchar_t>,class 
std::allocator<wchar_t> >,class std::allocator<class std::basic_string<wchar_t,struct 
std::char_traits<wchar_t>,class std::allocator<wchar_t> > > > > > __thiscall 
FileProcessing::FileProcessor::iterator::operator*(void)const "
(??Diterator@FileProcessor@FileProcessing@@QBE?AV?$vector@V?$vector@V?$basic_string@_WU?
$char_traits@_W@std@@V?$allocator@_W@2@@std@@V?$allocator@V?$basic_string@_WU?$char_traits
@_W@std@@V?$allocator@_W@2@@std@@@2@@std@@V?$allocator@V?$vector@V?$basic_string@_WU?$
char_traits@_W@std@@V?$allocator@_W@2@@std@@V?$allocator@V?$basic_string@_WU?$char_traits
@_W@std@@V?$allocator@_W@2@@std@@@2@@std@@@2@@std@@XZ) referenced in function "void 
__cdecl TestUnicodeSingleTable(void)" (?TestUnicodeSingleTable@@YAXXZ)

在这两个项目中,调用约定都在项目文件中指定为__cdecl。那么为什么会出现__thiscall,我该如何修复它呢?我必须使用__cdecl,因为我引用的是使用__cdecl的外部库。

其他项目设置:

两个项目都有以下配置设置:

  • "MFC的使用":在共享DLL中使用MFC
  • "使用ATL":不使用ATL
  • "字符集":使用Unicode字符集

看起来FileProcessingTests.cpp没有被重建,或者它使用了一个过时的头。该对象文件仍在尝试链接到std::wstring变体,而不是CString变体。

错误消息是一种详细的方式,表示未解析的外部符号用于:

std::vector<std::vector<std::wstring>> FileProcessor::iterator::operator*() const

请记住,std::wstring只是的typedef

class std::basic_string<wchar_t,struct std::char_traits<wchar_t>,class std::allocator<wchar_t> >

如果使默认模板参数显式。错误消息也使std::vector的默认模板参数显式,这就是为什么错误消息有如此可怕的喷出。

来自MSDN:

__thiscall调用约定用于成员函数执行以下操作的C++成员函数使用的默认调用约定不使用变量参数。

因此,__thiscall是方法的默认调用约定。这可能就是问题所在。

我建议尝试为您有问题的方法添加一个__cdecl,看看会发生什么。