奇怪的MFC / VC ++链接器错误(已定义std :: list <CRect>)
我收到一个非常奇怪的错误消息,该错误消息仅在将以下行添加到我的项目中时发生:
std::list<CRect> myVar;
值得注意的是,它不必是std :: list,也可以是std :: vector或者我假设的任何其他STL容器。
这是错误消息:
Error 1 error LNK2005: "public: __thiscall std::list ::list >(void)" (??0?$list@VCRect@@V?$allocator@VCRect<std<std@@QAE@XZ) already defined in SomeLowLevelLibrary.lib
错误消息中引用的低级库对我正在构建的项目一无所知,它仅具有核心低级功能,不处理高级MFC GUI。
如果将代码行更改为:我可以消除链接器错误:
std::list<CRect*> myVar;
但是我不想为此而乱砍。
此外,无论是在堆栈还是堆上创建变量都没有关系,我仍然会遇到相同的错误。
有人对此有任何想法吗?
我在Vista Enterprise上使用Microsoft Visual Studio 2008 SP1.
编辑:上面的链接器错误是针对std :: list <>构造函数的,我也为析构函数,_Nextnode和clear函数得到了错误。
编辑:在项目中的其他文件中,std :: vector将不会链接,在其他文件中,它可能是std :: list。我无法弄清楚为什么有些容器可以工作,而有些则不能。 MFC链接在两个库之间都是静态的。在低级库中,我们有1个类继承自std :: list。
编辑:低级库没有任何继承自CRect的类,但它确实使用了STL。
解决方案
这听起来不像是确切的症状,但是请确保我们应该检查主项目和所有包含的库在" C ++:Code Generation"下使用相同的" Runtime Library"设置。混合这些设置会创建运行时库链接错误。 (令我们困惑的是,我们可以通过更改代码来使它消失,但是值得检查一下是否还没有。)
SomeLowLevelLibrary.lib是否包含或者使用任何名为CRect的类?它使用STL吗?
我们应该查看链接器设置,但我不能立即说出哪个。在多个文件中完成STL实例化是正常的。链接器应选择一个。它们都是相同的(假设我们确实具有一致的编译器设置)。
该文件是否包含在标头中,可以将其编译成两个单独的代码模块?
今天,我脑海中又冒出了另一种可能性。我们当前的DLL和低级库是否可能引用了两个不同版本的MFC?远射。
我最近在我们的项目中再次偶然发现了此错误,并决定进行更彻底的调查,而不是像上次那样(使用CArray交换std :: list)对其进行修补。事实证明,我们的低级库之一是从std :: list继承的,例如
class LIB_EXPORT CRectList : public std::list<CRect> { };
这不仅是一种不好的做法,而且是主应用程序中链接器错误的原因。我将CRectList更改为包装std :: list而不是从中继承,错误消失了。