2016-06-13 126 views
-1

我一直在试图解决有关编译单元的问题。错误LNK2005结构已经定义在.obj文件中

我得到的错误是

1>frtinvxml.obj : error LNK2005: "struct repFieldInfo det_rep_info" ([email protected]@[email protected]@A) already defined in Frtinv.obj 
1>frtinvxml.obj : error LNK2005: "struct repFieldInfo frt_rep_info" ([email protected]@[email protected]@A) already defined in Frtinv.obj 
1>frtinvxml.obj : error LNK2005: "struct FormToolbar * tb" ([email protected]@[email protected]@A) already defined in Frtinv.obj 
1>frtinvxml.obj : error LNK2005: "struct tagDATE_STRUCT dateFrom" ([email protected]@[email protected]@A) already defined in Frtinv.obj 
... (It goes on for every variable and method in the header...) 

这是我得到的唯一错误。这里有包括参与顺序从最高的树,以最低的每一个相应的类...

***Frtinv.hxx*** 
#pragma once 

#include <voyage.ddh> 
#include <vsched.ddh> 
# ... 

struct frtinvType : public frtinv_type 
    { 
    int  fixCarSeq; 
    ... 

...

***frtinv.cxx*** 
//#define _IN_MAIN_ 
#include <decisionTable.h> 
... 

#define RINDEX 2 
#define LINDEX 2 
#define PINDEX 0 

BOOL s_fNeedSaveAfterDelete = FALSE; 
static int rateCnt = RINDEX, lumpCnt = LINDEX, pcntCnt = PINDEX; 


//------------------------------------------------------------------------ 
int getPortcar(char *vslCode, int voyNo, int portCallSeq, int berthSeq, int seq, portcar_type *pret) 
    ... 

...

***frtinvxml.h*** 
#define _IN_MAIN_ 

#include <iostream> 
#include <sstream> 
#include <stdio.h> 
#include <zdb.hxx> 
#include <opr32.h> 
#include <voyage.ddh> 
#include <frtinv.ddh> <------ Tried to add these two to the solution, that failed. 
#include <frtinv.hxx> <------ 

void exitGracefully(); 
std::list<voyage_type> getVoyages(); 

.. 。

***frtinvxml.cpp*** 
#include "frtinvxml.h" <------ taking everything from frtinvxml.h 

void main(int argc, char *argv[]) { 

    InitWinLib (10, 8); 
    ... 

我的问题梗fr ü事实上,即使我将文件放在相同的文件夹/解决方案中,我也无法让他们不定义自己两次。即使使用“一次编译指示”关键字。我也尝试使用旧的#define,不包括,如果它已经存在......那也不管用。

您有任何解决方案或建议?

回答

2

#pragma once防止在单个编译单元中多次包含标头 - 在这种情况下是一个.obj文件 - 并且错误明显指出frtinvxml.obj定义了已经在Frtinv.obj中定义的内容。两个独立的目标。两个单独的编译单元。

once在Frtinv.obj的情况下完美工作,在frtinvxml.obj的情况下也是如此。两者都有一个定义,否则源将不会编译。不幸的是,链接器试图将两个objs放到相同的输出中。

对此的两种解决方案取决于变量的使用方式,但两者都不要在标题中进行声明。它几乎总是结局不好。

解决方案1:在相应头

extern struct repFieldInfo det_rep_info; 

:所有的对象共享单个可变

定义。 extern tells the compiler某处det_rep_info将被声明,并且该编译应继续使用此外部det_rep_info

在CPP文件,frtinvxml.cpp,Frtinv.cpp,或在包含普通数据的一些第三CPP,申报

struct repFieldInfo det_rep_info; 

然后做同样的与其他三个重复的变量。

究竟在哪里放这些变量取决于个人的品味,选择和编码标准。编译此文件并将其与其他.obj文件链接起来,以便每个人都可以访问该变量。

解决方案2:所有的对象都有自己的私有变量

声明:本

static struct repFieldInfo det_rep_info; 
在需要它的每个CPP文件

。重复所有需要的变量。 static可确保每个det_rep_info仅在特定范围内可见。在这种情况下,一个编译单元。其中有一些微妙之处,所以read the documentation以确保static适合你。

您可以将声明放在标题中,并且标题的每个包含器都会得到自己的副本,但是需要注意的是,标题的每个包含器都会获得副本,无论他们是否需要它。不要为其他人做出这个决定。在需要它的cpp文件中声明变量。编译器会抓住它,如果你错过了。

+0

谢谢。很有帮助。这是我第一次真正使用C++(当然,它在工作中),所以感谢您的理解。 – Ian