Ian*_*Ian -1 c++ compilation pragma include
我一直在尝试处理有关编译单元的问题。
我得到的错误是
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...)
Run Code Online (Sandbox Code Playgroud)
这是我得到的唯一错误。以下是所涉及的每个相应类的包含,按从树上最高到最低的顺序...
***Frtinv.hxx***
#pragma once
#include <voyage.ddh>
#include <vsched.ddh>
# ...
struct frtinvType : public frtinv_type
{
int fixCarSeq;
...
Run Code Online (Sandbox Code Playgroud)
...
***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)
...
Run Code Online (Sandbox Code Playgroud)
...
***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();
Run Code Online (Sandbox Code Playgroud)
...
***frtinvxml.cpp***
#include "frtinvxml.h" <------ taking everything from frtinvxml.h
void main(int argc, char *argv[]) {
InitWinLib (10, 8);
...
Run Code Online (Sandbox Code Playgroud)
我的问题源于这样一个事实,即使我将文件放在同一个文件夹/解决方案中,我也无法让它们不定义自己两次。即使使用'pragma once' 关键字。我也尝试使用老式的#define,如果它已经存在,请不要包含......这也不起作用。
您有任何解决方案或建议吗?
#pragma once防止在单个编译单元中多次包含标头 - 在这种情况下为 .obj 文件 - 并且错误明确指出 frtinvxml.obj 定义了已经在 Frtinv.obj 中定义的内容。两个独立的对象。两个独立的编译单元。
once在 Frtinv.obj 和 frtinvxml.obj 的情况下完美地工作。两者都只有一个定义,否则源文件将不会被编译。不幸的是,链接器试图将两个 obj 放入相同的输出中。
对此有两种解决方案,具体取决于变量的使用方式,但两者都不要在标头中进行声明。它几乎总是以糟糕的结局结束。
定义:
extern struct repFieldInfo det_rep_info;
Run Code Online (Sandbox Code Playgroud)
在适当的标题中。extern告诉编译器某处det_rep_info将被声明并且编译应该继续使用这个外部det_rep_info.
在 cpp 文件 frtinvxml.cpp、Frtinv.cpp 或包含公共数据的某些第三个 cpp 中,声明
struct repFieldInfo det_rep_info;
Run Code Online (Sandbox Code Playgroud)
然后对其他三个重复变量执行相同操作。
将这些变量放在哪里取决于个人品味、选择和编码标准。编译此文件并将其与其他 .obj 文件链接,以便每个人都可以访问该变量。
宣布:
static struct repFieldInfo det_rep_info;
Run Code Online (Sandbox Code Playgroud)
在每个需要它的 cpp 文件中。对所需的所有变量重复此操作。static确保每个det_rep_info只在特定范围内可见。在这种情况下,单个编译单元。这里实际上有一些微妙之处,因此请阅读文档以确保static适合您。
您可以将声明放在标题中,标题的每个包含者都将获得自己的副本,但重要的是要注意标题的每个包含者都将获得一个副本,无论他们是否需要。不要替别人做这个决定。在需要它的 cpp 文件中声明变量。如果你错过了,编译器会抓住它。