C++ 在Visual Studio 2013中获取std::string方法和运算符的错误LNK2005
我有一个基于Qt的项目,我已经构建和使用visualstudio2008大约5年了。我构建并使用“调试”和“发布”构建配置 我正在迁移到VS2013,现在我在std::string方法和运算符上遇到了一些非常奇怪的LNK2005错误 代码库分为两个库和一组UI目录。在调试生成配置中,这两个库内置到DLL中,然后在运行其中一个UI时必须在路径中指定。在发布模式下,所有内容都静态编译为单个可执行文件。效果很好 这两个库是“model”和“engine”。首先建立“模型”,然后建立“引擎”。“引擎”使用“模型”(库) 当“引擎”被链接时,我会得到一系列以下错误,所有这些错误都与std::string有关:C++ 在Visual Studio 2013中获取std::string方法和运算符的错误LNK2005,c++,visual-studio-2013,stdstring,C++,Visual Studio 2013,Stdstring,我有一个基于Qt的项目,我已经构建和使用visualstudio2008大约5年了。我构建并使用“调试”和“发布”构建配置 我正在迁移到VS2013,现在我在std::string方法和运算符上遇到了一些非常奇怪的LNK2005错误 代码库分为两个库和一组UI目录。在调试生成配置中,这两个库内置到DLL中,然后在运行其中一个UI时必须在路径中指定。在发布模式下,所有内容都静态编译为单个可执行文件。效果很好 这两个库是“model”和“engine”。首先建立“模型”,然后建立“引擎”。“引擎”使
1>model.lib(model.dll) : error LNK2005: "public: class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >
& __thiscall std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >::operator=(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > const &)"
(??4?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAEAAV01@ABV01@@Z)
already defined in NamedObject.obj
1>model.lib(model.dll) : error LNK2005: "public:
int __thiscall std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >::compare(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > const &)const "
(?compare@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QBEHABV12@@Z)
already defined in NamedObject.obj
还有许多其他类似的LNK2005错误,但这一个是相当孤立的一个小类
我检查/验证的事项:
- 在本例中,我使用一致的“/Mxx”编译器选项(/MDd)编译和链接
- “-Zc:wchar\u t”选项在“model”和“engine”的makefile中都指定
- 两个库都与“/NOLOGO/DYNAMICBASE/NXCOMPAT/DEBUG/NODEFAULTLIB:LIBCMT/NODEFAULTLIB:LIBCPMT/NODEFAULTLIB:LIBCMTD/NODEFAULTLIB:LIBCPMTD/NODEFAULTLIB:MSVCRT/NODEFAULTLIB:MSVCPRT/MSVCPRT/DLL”链接
- 各种对象文件上的“dumpbin/dependencies”显示“/DEFAULTLIB:msvcprtd/DEFAULTLIB:msvctd/DEFAULTLIB:OLDNAMES”
?4?$basic_string@DU?$char_traits@D@性病病毒$allocator@D@2@@std@@QAEAAV01@PBD@Z(public:class std::basic_string&uu thiscall std::basic_string::operator=(char const*))
但是VS2008版本没有
编辑2好吧,我决定尝试一下。。。。。我已经将它隔离为几个小类(是的,所有的东西都是用相同版本的编译器、相同的VS解决方案等编译的)
下面是我对一个简单的“model”类的声明。我稍后会解释一些事情。您可以大致了解这些方法的实现
# pragma once
# if defined(WIN32) && defined(BUILD_DLL)
# if defined(MODEL_EXPORT_API) // inside DLL
# define MODEL_EXPORTAPI __declspec(dllexport)
# define MODEL_EXPIMP_TEMPLATE
# else // outside DLL
# define MODEL_EXPORTAPI __declspec(dllimport)
# define MODEL_EXPIMP_TEMPLATE extern
# endif
# else
# define MODEL_EXPORTAPI
# endif
# include <string>
# if defined (WIN32)
MODEL_EXPIMP_TEMPLATE template class MODEL_EXPORTAPI std::basic_string<char, std::char_traits<char>, std::allocator<char> >;
# endif
namespace model { namespace exceptions {
class MODEL_EXPORTAPI FlowException {
public:
FlowException(const std::string & m);
virtual ~FlowException();
virtual const char * what() const;
private:
// Copy constructor and assignment operator are private and
// unimplemented.
FlowException(const FlowException &);
FlowException & operator=(const FlowException &);
std::string _msg;
};
} }
#pragma一次
#如果已定义(WIN32)和已定义(BUILD_DLL)&&D
#如果已定义(模型导出API)//在DLL内部
#定义模型\u EXPORTAPI\u declspec(dllexport)
#定义模型导出模板
#else//外部DLL
#定义模型导出API declspec(dllimport)
#定义模型EXPIMP模板extern
#恩迪夫
#否则
#定义模型\导出API
#恩迪夫
#包括
#如果已定义(WIN32)
MODEL_EXPIMP_TEMPLATE模板类MODEL_EXPORTAPI std::basic_字符串;
#恩迪夫
命名空间模型{命名空间异常{
类模型\u导出API流异常{
公众:
FlowException(const std::string&m);
虚拟~FlowException();
虚拟常量char*what()常量;
私人:
//复制构造函数和赋值运算符是私有的且
//未执行。
FlowException(常量FlowException&);
FlowException&运算符=(常量FlowException&);
std::string\u msg;
};
} }
对于“引擎”类。这个类似于上面的“model”类。再一次,你可以用figger计算出它的实现是什么
# pragma once
# include <string>
# if defined(WIN32) && defined(BUILD_DLL)
# if defined(FLOWENGINE_EXPORT_API) // inside DLL
# define FLOWENGINE_EXPORTAPI __declspec(dllexport)
# define FLOWENGINE_EXPIMP_TEMPLATE
# else // outside DLL
# define FLOWENGINE_EXPORTAPI __declspec(dllimport)
# define FLOWENGINE_EXPIMP_TEMPLATE extern
# endif
# else
# define FLOWENGINE_EXPORTAPI
# endif
namespace flowEngine { namespace core {
class NamedObject {
public:
NamedObject(const std::string & n);
virtual ~NamedObject();
bool operator== (const NamedObject & v) const;
const char * getName() const;
private:
// Copy constructor and assignment operator are private and
// unimplemented.
NamedObject(const NamedObject &);
NamedObject & operator=(const NamedObject &);
std::string _name;
};
} }
#pragma一次
#包括
#如果已定义(WIN32)和已定义(BUILD_DLL)&&D
#如果已定义(FLOWENGINE\u EXPORT\u API)//在DLL内部
#定义FLOWENGINE\u EXPORTAPI\u declspec(dllexport)
#定义FLOWENGINE_EXPIMP_模板
#else//外部DLL
#定义FLOWENGINE\u EXPORTAPI\u declspec(dllimport)
#定义FLOWENGINE\u EXPIMP\u模板外部
#恩迪夫
#否则
#定义FLOWENGINE\u导出API
#恩迪夫
命名空间流引擎{命名空间核心{
类名对象{
公众:
NamedObject(const std::string&n);
虚拟~NamedObject();
布尔运算符==(常量NamedObject&v)常量;
常量char*getName()常量;
私人:
//复制构造函数和赋值运算符是私有的且
//未执行。
NamedObject(const NamedObject&);
NamedObject&运算符=(const NamedObject&);
std::string _name;
};
} }
现在进行测试
现在怎么办?在一个例子中,编译器告诉我修复代码,当我链接失败时……我正在迁移到VS2013,现在我在std::string方法和运算符上遇到一些非常奇怪的LNK2005错误。您是否对所有依赖项(包括Qt)都使用VS2013?是的。我已经使用VS2013重建了Qt。你确定要链接VS2013 CRT吗?编辑:等等,我看到你在
# pragma once
# include <string>
# if defined(WIN32) && defined(BUILD_DLL)
# if defined(FLOWENGINE_EXPORT_API) // inside DLL
# define FLOWENGINE_EXPORTAPI __declspec(dllexport)
# define FLOWENGINE_EXPIMP_TEMPLATE
# else // outside DLL
# define FLOWENGINE_EXPORTAPI __declspec(dllimport)
# define FLOWENGINE_EXPIMP_TEMPLATE extern
# endif
# else
# define FLOWENGINE_EXPORTAPI
# endif
namespace flowEngine { namespace core {
class NamedObject {
public:
NamedObject(const std::string & n);
virtual ~NamedObject();
bool operator== (const NamedObject & v) const;
const char * getName() const;
private:
// Copy constructor and assignment operator are private and
// unimplemented.
NamedObject(const NamedObject &);
NamedObject & operator=(const NamedObject &);
std::string _name;
};
} }