我已经跟踪一个大型项目中的错误三天了,终于得到了一个最小的可重现示例。我想分享这个问题,并就 Visual Studio 的奇怪行为提出一些问题。
当您导出从实例化模板类继承的类时,例如
class __declspec(dllexport) classA : public Template<double>{}
Run Code Online (Sandbox Code Playgroud)
MSVC还将导出Template<double>DLL中实例化的模板类。
如果消费者"template.h"在他的代码中包含然后同时实例化一个Template<double>, qnd ,链接到上面的DLL,他将得到两个 的定义Template<double>,这会导致LNK2005和LNK1169错误。Microsoft DLL 导出和 C++ 模板中讨论了此问题。
这是此问题的最小可重现示例(完整代码位于此处):
// ----------- Project AA ------------
// aa/CMakeLists.txt
cmake_minimum_required(VERSION 3.1)
project(AA)
add_library(AA SHARED classA.cpp) //(1)
set_target_properties(AA PROPERTIES COMPILE_FLAGS "-DBUILD_AA")
// aa/config.h
#pragma once
#ifdef _WIN32
# ifdef BUILD_AA
# define AA_API __declspec( dllexport )
# else
# define AA_API __declspec( dllimport )
# endif …Run Code Online (Sandbox Code Playgroud) 我找到了其他人遇到这个问题的例子,但他们的解决方案没有运气.我试图在一个也使用boost线程和绑定的静态库中使用std :: cout.当我不使用std::cout它并编译并与主程序良好链接,但当我这样做,我编译库我没有问题,但当我编译和链接使用静态库的主程序时,我得到了很多像:
2>LIBCMT.lib(crt0init.obj) : error LNK2005: ___xi_z already defined in MSVCRTD.lib(cinitexe.obj) 2>LIBCMT.lib(crt0init.obj) : error LNK2005: ___xc_a already defined in MSVCRTD.lib(cinitexe.obj) 2>LIBCMT.lib(crt0init.obj) : error LNK2005: ___xc_z already defined in MSVCRTD.lib(cinitexe.obj) 2>LIBCMT.lib(mlock.obj) : error LNK2005: __unlock already defined in MSVCRTD.lib(MSVCR100D.dll) 2>LIBCMT.lib(mlock.obj) : error LNK2005: __lock already defined in MSVCRTD.lib(MSVCR100D.dll) 2>LIBCMT.lib(winxfltr.obj) : error LNK2005: __XcptFilter already defined in MSVCRTD.lib(MSVCR100D.dll) 2>LIBCMT.lib(crt0.obj) : error LNK2005: _mainCRTStartup already defined in MSVCRTD.lib(crtexe.obj)
等等...
我已尝试进入我的链接器设置并停止使用错误输出中列出的冲突库,但我无法正确使用它.如果我告诉它停止使用一个库它可以解决问题,但给我一些遗漏的外部符号,然后我切换它有问题的库但我仍然得到一些"已经定义".有什么线索可以解决这个问题吗?我应该只创建另一个名为"log"或类别的类,只需从主.exe访问它(这将使用字符串库,这可能会再次引起问题,但我还没有尝试过)?感谢您的任何帮助.
1>Deck.obj : error LNK2005: "class Card card" (?card@@3VCard@@A) already defined in Card.obj
1>PokerTester.obj : error LNK2005: "class Card card" (?card@@3VCard@@A) already defined in Card.obj
1>PokerTester.obj : error LNK2005: "class Deck deck" (?deck@@3VDeck@@A) already defined in Deck.obj
1>C:\Dev\Poker\Debug\Poker.exe : fatal error LNK1169: one or more multiply defined symbols found
Run Code Online (Sandbox Code Playgroud)
我已经通过谷歌搜索了解到为什么会发生这些错误,但我不知道为什么当我尝试过 #pragma once 和 #ifndef 保护事情时它们仍然发生。
这是我的 Card.h
#pragma once
#ifndef CARD_H
#define CARD_H
#include <iostream>
#include <string>
using namespace std;
class Card
{
public:
Card(int cardSuit = 0, int cardValue = …Run Code Online (Sandbox Code Playgroud) 我有一个模板化的类Child,它继承自非模板化的Parent类.当我在多个.cpp文件中包含Child的标头时,我收到LNK2005错误.发生这种情况是因为Parent在多个编译单元中定义.当这些单元链接在一起时,它们会导致LNK2005错误.
如果你想知道的目的,父母是给孩子的都是一个静态变量子实例,而不是只为每个儿童<""类型""> .
我的问题是,如何创建一个模板化的类,它具有唯一的(跨所有子实例)静态变量,并且可以包含在多个.cpp文件中?
这是一个导致LNK2005错误的玩具示例:
main.cpp中
#include "Apple.h"
#include "Banana.h"
#include <string>
void main() {
Apple apple;
Banana banana;
}
Run Code Online (Sandbox Code Playgroud)
Apple.h
#ifndef APPLE_H
#define APPLE_H
struct Apple {
Apple();
};
#endif // APPLE_H
Run Code Online (Sandbox Code Playgroud)
Apple.cpp
#include "Apple.h"
#include "Child.h"
Apple::Apple() {
Child<int> child;
child.foo(5);
}
Run Code Online (Sandbox Code Playgroud)
Banana.h
#ifndef BANANA_H
#define BANANA_H
struct Banana {
Banana();
};
#endif // BANANA_H
Run Code Online (Sandbox Code Playgroud)
Banana.cpp
#include "Banana.h"
#include "Child.h"
Banana::Banana() …Run Code Online (Sandbox Code Playgroud) 我有一个似乎是一个常见的问题,但我似乎无法在我的代码的上下文中解决它.我最近开始上课,我已经被投入C++和OpenGL而没有C++的先前知识,所以请对我很轻松.这是我的3个文件,用于打开OpenGL窗口; 但是我遇到了一个不错的LNK2005错误:
错误LNK2005:"public:static unsigned int JWindow :: id"(?id @ JWindow @@ 2IA)已在Application.obj X中定义:\ School\comp2501\COMP2501Tutorial1\COMP2501Tutorial1\Main.obj COMP2501Tutorial1
我似乎无法找到我重新定义的东西给我这个错误.
main.cpp中
#include <windows.h> // Standard header for MS JWindows applications
#include <freeglut.h>
#include "Application.h"
#define KEY_ESCAPE 27
static GLfloat lightPos[] = { 1.0, 1.0, 1.0, 0.0 };
void drawCube(GLdouble x0, GLdouble x1, GLdouble y0, GLdouble y1, GLdouble z0, GLdouble z1) {/**/}
int main(int argc, char **argv) {
JWindow::create(640, 480, "Tutorial 1", 45.0f, 0.1f, 500.0f);
// initialize and run program
glutInit(&argc, argv); // GLUT initialization …Run Code Online (Sandbox Code Playgroud) 当我遇到 lnk2005 错误时,我正在玩命名空间。我不知道如何解决这个错误。这是错误:
1>Source.obj : error LNK2005: "int Chart::Bars::d" (?d@Bars@Chart@@3HA) already defined in Chart.obj
1>Source.obj : error LNK2005: "class foo Chart::l" (?l@Chart@@3Vfoo@@A) already defined in Chart.obj
1>Source.obj : error LNK2005: "int Chart::t" (?t@Chart@@3HA) already defined in Chart.obj
1>C:\Users\bnm\dev\examples\play\nmspca\Debug\nmspca.exe : fatal error LNK1169: one or more multiply defined symbols found
1>
1>Build FAILED.
1>
1>Time Elapsed 00:00:00.49
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
Run Code Online (Sandbox Code Playgroud)
这是代码...
图表.h
#pragma once
#include "foo.h"
namespace Chart
{
int t;
foo l; …Run Code Online (Sandbox Code Playgroud) 我有一个大项目。
在N.cpp我需要使用boost::filesystem::exists(path)检查路径是否有效。
为此,我包括 <boost/filesystem.hpp>
我收到以下错误:
Error 2 error LNK2005: "public: enum boost::filesystem::file_type __cdecl boost::filesystem::file_status::type(void)const " (?type@file_status@filesystem@boost@@QEBA?AW4file_type@23@XZ) already defined in N.obj D:\MProject\DA\boost_filesystem-vc100-mt-gd-1_53.lib(boost_filesystem-vc100-mt-gd-1_53.dll) DA
Error 1 error LNK2005: "public: __cdecl boost::filesystem::path::~path(void)" (??1path@filesystem@boost@@QEAA@XZ) already defined in N.obj D:\MProject\DAboost_filesystem-vc100-mt-gd-1_53.lib(boost_filesystem-vc100-mt-gd-1_53.dll) DA
Error 3 error LNK1104: cannot open file 'libboost_filesystem-vc100-mt-gd-1_53.lib' D:\MProject\DA\LINK DA
Run Code Online (Sandbox Code Playgroud)
如果不包含头文件,则会得到:
Error 2 error C3861: 'exists': identifier not found D:\MProject\DA\ThirdParty\N.cpp 108 1 DA
Error 1 error C2653: 'boost' : is not a class or namespace name D:\MProject\DA\ThirdParty\N.cpp 108 1 DA …Run Code Online (Sandbox Code Playgroud) 我遇到这个问题,如果我包含某个标头,则无法编译。
标题的代码:
//#include "tinyxml2.h"
#pragma once
#include "Camera.h"
#include "Controller.h"
#include "Lights.h"
#include "Mesh.h"
namespace ActorFactory {
//using namespace tinyxml2;
template<class T>
Actor* createInstance() {
return new T;
}
typedef std::map<std::string, Actor*(*)()> class_map;
class_map test = {
{ "Camera", &createInstance<Camera> }
//{ "Mesh", &createInstance<Mesh> }
};
}
Run Code Online (Sandbox Code Playgroud)
来自 Visual Studio 的完整错误消息:
1>------ Build started: Project: ogl_inf251_ca2, Configuration: Debug Win32 ------
1> Main.cpp
1>d:\development\inf251\ogl_inf251_ca2\model_obj.h(26): warning C4005: '_CRT_SECURE_NO_WARNINGS' : macro redefinition
1> command-line arguments : see previous definition of '_CRT_SECURE_NO_WARNINGS'
1> Generating …Run Code Online (Sandbox Code Playgroud) c++ ×8
lnk2005 ×8
templates ×2
boost ×1
dll ×1
factory ×1
header ×1
header-files ×1
include ×1
inheritance ×1
object ×1
visual-c++ ×1