我有一个大型项目,旨在控制和测试硬件。
有4个设备控制类别(用于干涉仪、压电电机、PXI系统和纳米定位控制器)。
我创建了一个名为MainIO的“主”类,它存储了上述每个类的一个实例,以便在IO范围内执行操作(即移动电机和检查干涉仪)。MainIO头文件包括4个控件类头。
然后我有一个单独的“全局”hpp/cpp,它包含全局变量、转换、ini文件操作等。这是使用操作类型的名称空间进行布局的,而不是创建类,即GCONV::someFunction();和GMAIN::controllerModel;
我需要所有4个控制类来访问转换和其他全局操作。我曾经有过包括global.hpp在内的所有东西,但是我已经改变了一些东西(我不知道它会是什么!)现在看来,我无法在任何控制类hpp或cpp中包含global.hpp,而不会收到链接器错误-
global.obj:-1: error: LNK2005: "class QString GMAIN::controllerModel" (?controllerModel@GMAIN@@3VQString@@A) already defined in controllers.obj
我绝对确定我做了什么愚蠢的事情,解决方案就在我面前,但它已经到了让我如此沮丧的地步,以至于我看不到树木而看到了森林。
发布于 2014-11-14 19:18:37
我已经发现我做错了什么,尽管它非常简单,但我花了一段时间才找到相关文档来发现我的错误,所以我将回答我自己的问题,希望能给别人一个更轻松的时间。
事实证明,在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
}发布于 2014-11-14 19:15:11
您是否正在定义controllerModel,而您应该只声明它?http://www.cprogramming.com/declare_vs_define.html
发布于 2014-11-14 19:53:00
您应该导出您的dll。使用__declspec(dllexport)。您可以将__declspec(dllexport)作为宏包含在头文件中,并将该宏放在每个成员函数的开头。
例如:在您的Header.h文件中包含
#define MYMACRO __declspec(dllexport);在你的班上
class classname
{
public:
MYMACRO void MYFUNCTION();
MYMACRO void MYFUNCTION2();
};https://stackoverflow.com/questions/26927985
复制相似问题