2016-06-13 8 views
-1

저는 컴파일 단위와 관련된 문제를 해결하려고 노력해 왔습니다.오류 LNK2005 struct가 .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.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) 
    ... 

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

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

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

...

***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 사실, 같은 폴더/솔루션에 파일을 놓을지라도 두 번 정의하지 않도록 할 수는 없습니다. 'pragma once'키워드를 사용하는 경우에도. 나는 또한 오래된 학교 #define을 사용하여 시도했다. 이미 존재한다면 ... 포함시키지 않는다. 그것은 역시 작동하지 않는다.

해결책이나 권장 사항이 있습니까?

답변

2

#pragma once은 단일 컴파일 단위 (이 경우 .obj 파일)에 헤더가 여러 번 포함되는 것을 방지하며 frtinvxml.obj는 Frtinv.obj에 이미 정의 된 내용을 정의합니다. 두 개의 분리 된 객체. 두 개의 별도 컴파일 단위.

once은 Frtinv.obj의 경우 완벽하게 작동하고 frtinvxml.obj의 경우 다시 작동합니다. 두 가지 모두 소스가 컴파일되지 않았을 경우 정확히 하나의 정의를가집니다. 불행히도 링커는 두 obj를 동일한 출력에 넣으려고합니다.

변수가 사용되는 방법에 따라 두 가지 해결책이 있지만 두 가지 모두 헤더에 선언을하지 마십시오. 거의 항상 나 빠지게됩니다.

해결 방법 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 : 모든 개체가 자신의 개인 변수

선언을 필요로하는 각 CPP 파일에

static struct repFieldInfo det_rep_info; 

. 필요한 모든 변수에 대해 반복하십시오. static은 각 det_rep_info이 특정 범위 내에서만 볼 수 있도록합니다. 이 경우 단일 컴파일 단위. 실제로 약간의 미묘함이 있으므로 이 맞는지 확인하려면 read the documentation을 사용하십시오.

선언문을 헤더에 넣을 수 있으며 헤더의 각 includer에 고유 한 복사본이 생기지 만, 헤더의 모든 includer는 원하는지 여부에 관계없이 복사본을 얻을 수 있습니다. 다른 사람들을 위해이 결정을하지 마십시오. 필요로하는 cpp 파일에서 변수를 선언하십시오. 당신이 그것을 놓친다면 컴파일러는 그것을 잡을 것이다.

+0

감사합니다. 매우 도움이됩니다. C++로 실제로 작업 한 것은 이번이 처음입니다. (그리고 물론 작동 중입니다.) 이해해 주셔서 감사합니다. – Ian