我一直在尝试处理有关编译单元的问题。
我得到的错误是
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);
...
我的问题源于这样一个事实:即使我将文件放在同一个文件夹/解决方案中,我也无法让他们自己定义两次。即使使用&#39; pragma一次&#39;关键词。我也试过使用旧学校#define,如果它已经存在则不要包括......那也不起作用。
您有任何解决方案或建议吗?
答案 0 :(得分:4)
#pragma once
防止在单个编译单元中多次包含标头 - 在这种情况下为.obj文件 - 并且错误明确指出frtinvxml.obj定义了已在Frtinv.obj中定义的内容。两个独立的objs。两个独立的编译单元。
once
在Frtinv.obj的情况下完美地工作,在frtinvxml.obj的情况下再次工作。两者都有一个定义,否则源不会编译。不幸的是,链接器试图将两个obj放入相同的输出中。
两种解决方案,取决于如何使用变量,但两者都不在标头中进行声明。它几乎总是很糟糕。
定义:
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文件链接,以便每个人都可以访问该变量。
宣告:
static struct repFieldInfo det_rep_info;
在需要它的每个cpp文件中。对所有需要的变量重复此操作。 static
确保每个det_rep_info
仅在特定范围内可见。在这种情况下,单个编译单元。实际上有一点微妙,所以read the documentation以确保static
适合你。
您可以将声明放在标题中,标题的每个包含者都会获得自己的副本,但重要的是要注意标题的每个包含者都会得到一个副本,无论他们是否需要。不要为其他人做出这个决定。在需要它的cpp文件中声明变量。如果你错过了,编译器会抓住它。