3

我有一个代码块项目,它使用许多不同的文件——通常是由其他程序员编写的。目前,我有两个不同的子项目,其中包含以相同方式命名的函数。假设:F(int x)。所以 F(int x) 在两个不同位置的两个源文件中定义,它们有两个不同的标题。我还为这些标头创建了两个不同的命名空间:

namespace NS1
{
 extern "C"{
  #include "header1definingF.h"
 }
}
namespace NS2
{
 extern "C"{
  #include "header2definingF.h"
 }
}

但是编译器仍然抱怨它有多个 F(int x) 的定义。我如何在 Code::Blocks 中解决这个问题(在 Visual Studio 中它工作得很好)。

编辑:为了更清楚,这些标题包括 C 代码。没想到会这么乱 有成千上万的源文件使用其他项目,包括数千个功能......所以该怎么办。我完全不知道如何使它工作。

4

6 回答 6

6

我想知道为什么它适用于 Visual Studio,但不适用于代码块。这表明您确实有一个包含防护。有帮助吗?

Project->Build options...->Linker settings (tab)
-Wl,--allow-multiple-definition
于 2013-07-22T15:34:57.243 回答
3

我无法清楚地理解您的问题,但我认为您应该了解编译器的工作原理,当您使用 gcc 强制程序时,您的程序首先会运行包含运算符,这意味着如果您包含标头,编译器将复制头文件到文件。如果两次包含标题,则会出现两次定义错误。所以你必须保证一次,你可以使用

#ifndef __FILE_NAME__
#define __FILE_NAME__
// your code
#endif

如果你的问题是重新定义函数,你应该知道编译器是如何区分函数的,我认为你的问题是你在使用函数时没有使用命名空间。

于 2013-07-22T14:30:02.320 回答
3

问题是命名空间不适用于 C 函数(extern "C")。这是一个不编译的简单示例:

namespace NS1
{
 extern "C"{
  int f()
  {
   return 1;
  }
 }
}
namespace NS2
{
 extern "C"{
  int f()
  {
   return 2;
  }
 }
}

在这种情况下,这两个函数不同但具有相同的名称:f()。如果您只是声明函数,它将编译但它们必须引用相同的函数。

第二个示例工作正常。这些函数的名称 NS1::f() 和 NS2::f() 是不同的。

namespace NS1
{
 int f()
 {
  return 1;
 }
}
namespace NS2
{
 int f()
 {
  return 2;
 }
}

如果你想使用两个不同的 c 代码,你可以使用 objcopy,它可以帮助你拥有一个 NS1_f() 和 NS2_f() 函数。之后,您应该重命名包含中库的所有功能。在这种情况下,不使用命名空间。这很正常,C 中没有命名空间。等效函数:

int NS1_f()
{
 return 1;
}
int NS2_f()
{
 return 2;
}
于 2016-02-19T09:44:12.550 回答
1

您可能需要两件事之一。以下称为Header Guard

#ifndef MYHEADER_H
#define MYHEADER_H

//your header code goes here

#endif

这样,每个请求它的目标文件只包含一次标题。但是,如果您想拥有两个具有相同标识符的方法,它们必须属于不同的Namespaces

namespace myspace1{
    void func(void);
};
namespace myspace2{
    void func(void);
};

除此之外,你真的无能为力。一般来说,你不应该有两个同名的函数。此外,您必须在您提到的头文件中修改它。

您可以随意声明函数,但它们只能有一个定义。

于 2013-07-22T14:45:01.190 回答
1

我相信您还必须编辑 cpp 文件以将这两个函数嵌套到相应的命名空间中。另外,您必须选择要调用的函数,namespace::function()或者您可以using namespace与您创建的任一命名空间一起使用。希望这可以帮助!

[更新 #1] 函数的声明定义更容易混淆。请记住,您可以重新声明非成员函数。因此,如果头文件仅包含非成员函数声明,则可以安全地将其多次包含在一个翻译单元(cpp 文件)中。在头文件中添加ifndef/define是避免潜在问题的好习惯,但这并不能解决您的问题。

您的问题是您希望有两个具有相同函数签名(其名称和参数)的不同函数定义,而这在 C++ 中是不允许的。您可以更改其中一个签名或将它们放入不同的命名空间(您正在尝试但不触及它们的定义)。这两种方式都要求您编辑包含其定义的文件。

[更新 #2] 当您更新代码在 C 中的问题时,我搜索并发现了这一点:

如果两个库提供同名函数产生冲突怎么办?

它肯定会帮助您更清楚地了解您的问题并找到解决方案。祝你好运!

于 2013-07-22T14:29:45.333 回答
1

缺少编辑 .cpp 文件本身并重命名函数(这不是一个实际的解决方案),您的选择是确保一次只包含一个具有重复函数的头文件(这可能是一个巨大的维护问题)或者,这是我的建议,使用namespaces。在这种情况下,它们将为您节省大量麻烦。

于 2013-07-22T14:34:16.420 回答