2016-06-13 123 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