没有LNK2005错误,不能包含C ++标头

时间:2014-11-14 10:33:46

标签: c++ header linker include lnk2005

我有一个大型项目,旨在控制和测试硬件。

有4种设备控制等级(用于干涉仪,压电马达,PXI系统和纳米定位控制器)。

我创建了一个"主人"名为MainIO的类,它存储上述每个类的实例,以便在IO范围内执行操作(即移动电机和检查干涉仪)。 MainIO头文件包含4个控件类头。

然后我有一个单独的"全球" hpp / cpp,包含全局变量,转换,ini文件操作等。这是针对操作类型的名称空间而不是创建类,即GCONV::someFunction();GMAIN::controllerModel;

我需要所有4个控件类才能访问转换和其他全局操作。我曾经把它们全部包括在global.hpp中,但我已经改变了一些东西(我无法想象它会是什么!)现在似乎我无法在任何控件中包含global.hpp类hpp或cpp没有收到链接器错误 -

global.obj:-1: error: LNK2005: "class QString GMAIN::controllerModel" (?controllerModel@GMAIN@@3VQString@@A) already defined in controllers.obj

我绝对肯定我做了一些愚蠢的事情并且解决方案正在盯着我,但它已经到了我对它感到沮丧的阶段我无法看到树木的木材。

3 个答案:

答案 0 :(得分:1)

我发现了我做错了什么,虽然这很简单,但我花了一段时间才找到相关文档来发现我的错误,所以我会回答我自己的问题,希望能给别人一个更容易的时间。

事实证明,在global.hpp中,我在命名空间中声明变量,如下所示:

namespace GMAIN {
    QString controllerModel;
}

基本上这意味着包含global.hpp的每个文件都将包含自己的QString controllerModel定义,从而引发链接器错误。每个控件类都有自己对同一命名变量的定义,违反了一个定义规则。

要解决此问题,需要将QString controllerModel外部化。 extern关键字允许变量在多个位置声明,而只有一个定义(因此不会违反规则)。

现在工作代码是:

//in global.hpp
namespace GMAIN {
    extern QString controllerModel; //declaration - this is called for each `#include global.hpp`
}

//in global.cpp
namespace GMAIN {
    QString controllerModel; //definition - only called once as .cpp is never included
}

答案 1 :(得分:0)

您是否定义了controllerModel,您应该只声​​明它? http://www.cprogramming.com/declare_vs_define.html

答案 2 :(得分:0)

你应该导出你的DLL。 使用__declspec(dllexport)。您可以在头文件中包含__declspec(dllexport)作为宏,并将宏放在每个成员函数的开头。

例如: 在您的Header.h文件中包含

#define MYMACRO __declspec(dllexport);

并在你的班级

class classname
{
  public:
  MYMACRO void MYFUNCTION();
  MYMACRO void MYFUNCTION2();
};