2016-06-13 27 views
-1

Ich habe versucht, ein Problem in Bezug auf Kompilierungseinheiten zu behandeln.Fehler LNK2005-Struktur bereits in .obj-Datei definiert

Der Fehler Ich erhalte ist

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...) 

Dies ist der einzige Fehler, den ich immer bin. hier sind die, um auf dem Baum zu niedrigsten vom höchsten beteiligt zu jedem jeweiligen Klassen gehören ...

***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); 
    ... 

Mein Problem stammt fr om die Tatsache, dass ich, selbst wenn ich die Dateien in den gleichen Ordner/Lösung platziere, sie nicht dazu bringen kann, sich nicht zweimal zu definieren. Auch wenn Sie das Schlüsselwort "Pragma einmal" verwenden. Ich habe auch versucht, die alte Schule #define, nicht zu verwenden, wenn es bereits existiert ... das hat auch nicht funktioniert.

Haben Sie irgendwelche Lösungen oder Empfehlungen?

Antwort

2

verhindert die mehrfache Aufnahme eines Headers in einer einzigen Kompilierungseinheit - in diesem Fall eine OBJ-Datei - und der Fehler besagt eindeutig, dass frtinvxml.obj etwas definiert, das bereits in Frtinv.obj definiert wurde. Zwei getrennte Objekte. Zwei separate Kompilierungseinheiten.

once funktionierte perfekt im Fall von Frtinv.obj und wieder im Fall von frtinvxml.obj. Beide haben genau eine Definition, sonst hätten die Quellen nicht kompiliert. Leider versucht der Linker, beide Objekte in die gleiche Ausgabe zu bringen.

Zwei Lösungen hierfür, abhängig davon, wie die Variable verwendet werden soll, aber für beide keine Deklarationen in Kopfzeilen. Es endet fast immer schlecht.

Lösung 1: Alle Objekte teilen sich eine einzige Variable

definieren:

extern struct repFieldInfo det_rep_info; 

im entsprechenden Header. extern tells the compiler, dass irgendwo det_rep_info wird deklariert werden und diese Kompilierung sollte weiterhin diese externe det_rep_info verwenden.

In einer CPP-Datei, frtinvxml.cpp, Frtinv.cpp oder in einer dritten cpp, die gemeinsamen Daten enthält, erklärt

struct repFieldInfo det_rep_info; 

dann mit dem anderen drei duplizierten Variablen das gleiche tun.

Wo genau diese Variablen platziert werden, hängt von persönlichem Geschmack, Auswahl und Codierungsstandard ab. Kompilieren Sie diese Datei und verknüpfen Sie sie mit den anderen OBJ-Dateien, damit alle auf die Variable zugreifen können.

Lösung 2: Alle Objekte verfügen über eine eigene Variable

Declare:

static struct repFieldInfo det_rep_info; 

in jeder CPP-Datei, die sie benötigt. Wiederholen Sie dies für alle erforderlichen Variablen. static stellt sicher, dass jeder det_rep_info nur innerhalb eines bestimmten Bereichs sichtbar ist. In diesem Fall eine einzelne Kompilierungseinheit. Es ist tatsächlich ein bisschen Feinheit drin, also read the documentation um sicherzustellen, dass static für Sie richtig ist.

Sie könnten die Deklaration in die Kopfzeile einfügen, und jeder Incluender der Kopfzeile erhält eine eigene Kopie, aber es ist wichtig zu beachten, dass jeder Inclunder der Kopfzeile eine Kopie erhält, ob sie es will oder nicht. Treffen Sie diese Entscheidung nicht für andere Menschen. Deklarieren Sie die Variable in den cpp-Dateien, die sie benötigen. Compiler wird es fangen, wenn Sie einen verpassen.

+0

Vielen Dank. Sehr hilfreich. Dies ist das erste Mal, dass ich tatsächlich mit C++ gearbeitet habe (und natürlich bei der Arbeit). Danke für das Verständnis. – Ian