错误 LNK2005 结构已在 .obj 文件中定义

error LNK2005 struct already defined in .obj file

我一直在尝试处理有关编译单元的问题。

我得到的错误是

1>frtinvxml.obj : error LNK2005: "struct repFieldInfo det_rep_info" (?det_rep_info@@3UrepFieldInfo@@A) already defined in Frtinv.obj
1>frtinvxml.obj : error LNK2005: "struct repFieldInfo frt_rep_info" (?frt_rep_info@@3UrepFieldInfo@@A) already defined in Frtinv.obj
1>frtinvxml.obj : error LNK2005: "struct FormToolbar * tb" (?tb@@3PAUFormToolbar@@A) already defined in Frtinv.obj
1>frtinvxml.obj : error LNK2005: "struct tagDATE_STRUCT dateFrom" (?dateFrom@@3UtagDATE_STRUCT@@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);
    ...

我的问题源于这样一个事实,即即使我将文件放在同一个 folder/solution 中,我也无法让它们不定义自己两次。即使使用 'pragma once' 关键字。我也试过使用老派的#define,如果它已经存在就不要包含...那也不起作用。

您有什么解决方案或建议吗?

#pragma once 阻止在单个编译单元中多次包含 header - 在这种情况下是一个 .obj 文件 - 错误明确指出 frtinvxml.obj 定义了一些东西已在 Frtinv.obj 中定义。两个独立的对象。两个独立的编译单元。

once 在 Frtinv.obj 的情况下完美运行,在 frtinvxml.obj 的情况下再次运行。两者都有完全相同的定义,否则源代码将无法编译。不幸的是,linker 试图将两个 objs 放入相同的输出中。

这有两种解决方案,具体取决于变量的使用方式,但两者都不要在 header 中进行声明。它几乎总是以糟糕的方式结束。

解决方案 1:所有 objects 共享一个变量

定义:

extern struct repFieldInfo det_rep_info;

在合适的header。 extern tells the compiler 某个地方 det_rep_info 将被声明并且编译应该继续使用这个外部 det_rep_info.

在 cpp 文件中,frtinvxml.cpp、Frtinv.cpp,或在包含公共数据的第三个 cpp 中,声明

struct repFieldInfo det_rep_info;

然后对其他三个重复的变量执行相同的操作。

具体将这些变量放在哪里取决于个人品味、选择和编码标准。编译此文件并将其 link 与其他 .obj 文件一起使用,以便每个人都可以访问该变量。

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

声明:

static struct repFieldInfo det_rep_info;

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

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