如何安全地设置C / C ++项目(文件组织)

时间:2013-07-22 16:01:47

标签: include organization

我有一个(大型)C / C ++项目,它包含C和C ++语言。在某些时候,事实证明有两个具有相同名称的C函数。这些函数在不同位置的两个不同* .c文件中定义。通常在最高级别,该项目是C ++。这个问题受到质疑并回答here

然而,仍然存在“如何安全地组织这些文件”的问题。如何对这样的项目进行分组,以便没有名称冲突,我可以确定调用了正确的函数。为每个函数编写一个包装器会有帮助吗?

它看起来如何: A.h //首次声明函数F. A.c //函数F的第一个定义

B.h //功能F的第二次声明 B.c //函数F的第二个定义

试图做出这样的事情:

extern "C"{
#include "A.h"
#include "B.h"
}

当然名称冲突的原因。我该怎么做才能避免这种混乱,并拥有强大的代码?这样的解决方案会有所帮助:

A_Wrapper.h:// c ++

extern "C"{
#include "A.h"
}

void WrapF_A(int x)
{
  F(x);
}

B_Wrapper.h:// C ++

extern "C"{
#include "B.h"
}

void WrapF_B(int x)
{
  F(x);
}

然后在程序中:

#include A_Wrapper.h
#include B_Wrapper.h

对于该项目中的每个文件来说,相当不可能,因为它有数百个文件,我可能会损坏一些代码。有没有办法只在程序的某些部分看到包含文件?

编辑: 所以我创建了一个简单的项目来说明问题,并尝试应用doctorlove提供的提示。但是仍然会出现F错误的多重定义。我应该改变什么?项目文件:

A.H:

#ifndef A_H_INCLUDED
#define A_H_INCLUDED

int F(int x);

#endif // A_H_INCLUDED

A.C

#include "A.h"

int F(int x)
{
   return x*x;
}

AWrapper.h:

#ifndef AWRAPPER_H_INCLUDED
#define AWRAPPER_H_INCLUDED

int AF(int x);

#endif // AWRAPPER_H_INCLUDED

AW.cpp:

#include "AWrapper.h"
extern "C"{
#include "A.h"
}

int AF(int x)
{
   return F(x);
}

B.h:

#ifndef B_H_INCLUDED
#define B_H_INCLUDED

int F(int x);

#endif // B_H_INCLUDED

B.c:

#include "B.h"

int F(int x)
{
   return -x*x;
}

BWrapper.h:

#ifndef BWRAPPER_H_INCLUDED
#define BWRAPPER_H_INCLUDED

int BF(int x);

#endif // BWRAPPER_H_INCLUDED

BW.cpp:

#include "BWrapper.h"
extern "C"{
#include "B.h"
}

int BF(int x)
{
   return F(x);
}

1 个答案:

答案 0 :(得分:1)

继续你的包装理念,但写一个facade(另见here),从A公开你需要的东西,你需要从B 而不是所有的东西那里的功能。

你最终会得到像

这样的东西
//header Wrap_A.h
#ifndef WRAP_A_INCLUDED
#define WRAP_A_INCLUDED

//for some input Data left as an exercise for the reader...
double solve_with_A(Data data);

#endif


//header Wrap_B.h
#ifndef WRAP_B_INCLUDED
#define WRAP_B_INCLUDED

//for some input Data...
double solve_with_B(Data data);

#endif

然后制作两个cpp文件,其中包含所有冲突的头文件,A.cpp中的A和B.cpp中的B,因此冲突不会发生。 solve_with_Asolve_with_B函数将调用所需的所有内容,而不会将它们泄露给整个程序并导致冲突。

您可能需要考虑Data实际上会是什么。您可以定义自己的类型,一个用于A,另一个用于B。只是避免在包装/外观标题中公开实现细节。
如果标题让你感到痛苦,可以在顽皮的角落防范它们。


修改

鉴于您有两个函数F,如果您将所有源都放入一个项目中,链接器应该并且会抱怨它可以看到两者。相反,您需要创建两个静态库,并将包装的版本公开给您的主项目。