【问题标题】:How to setup C/C++ project safely (file organisation)如何安全地设置 C/C++ 项目(文件组织)
【发布时间】:2013-07-22 16:01:46
【问题描述】:

我有一个(大型)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 错误的多重定义。我应该改变什么?项目文件:

啊哈:

#ifndef A_H_INCLUDED
#define A_H_INCLUDED

int F(int x);

#endif // A_H_INCLUDED

交流

#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

公元前:

#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);
}

【问题讨论】:

  • 我们现在可能正在解决错误的问题。为什么将两个标题都包含在同一个源文件中?你不能只包括你需要的吗?
  • 我正在使用 Umfpack 和 SuperLU 库。在一个程序中,我需要两个求解器来执行不同的计算。而且这两个库都很少有名称完全相同的函数。

标签: include organization


【解决方案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,如果你把所有的源代码放到一个项目中,链接器应该并且会抱怨它可以同时看到这两个函数。相反,您需要创建两个静态库,并将包装的版本公开给您的主项目。

【讨论】:

  • 我创建了一个描述问题的小项目,但仍然出现错误说有多个定义。
  • 我已编辑问题。我添加了一个简单的问题说明,并将您的解决方案应用于它(据我所知)。但是问题仍然存在。
  • 好的。谢谢。我仍然认为可以避免创建库。但这没关系。感谢您的帮助。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-06-02
  • 2010-09-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-04-13
  • 2010-09-20
相关资源
最近更新 更多