我在代码块中有一个项目,它使用许多不同的文件 - 通常由其他程序员编写。目前我的情况是,我有两个不同的子项目,包含以相同方式命名的函数。比方说: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代码。我没想到它会如此凌乱。有数千个源文件使用其他项目,包括数以千计的功能......所以该怎么做。我完全不知道如何让它发挥作用。
答案 0 :(得分:4)
我想知道为什么它适用于Visual Studio,但不适用于代码块。这表明你确实有一个包含守卫。 this有帮助吗?
Project->Build options...->Linker settings (tab)
-Wl,--allow-multiple-definition
答案 1 :(得分: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;
}
答案 2 :(得分:2)
我无法清楚地理解你的问题,但我认为你应该理解编译器是如何工作的,当你使用gcc来强制你的程序时,你的程序首先会运行include运算符,这意味着如果你包含一个头,那么编译器会将头文件复制到该文件中。如果你包括两次标题会有两次定义错误。所以你必须保证一次,你可以使用
#ifndef __FILE_NAME__
#define __FILE_NAME__
// your code
#endif
如果您的问题是重新定义函数,您应该知道编译器如何区分函数,我认为您的问题是您在使用函数时不使用命名空间。
答案 3 :(得分:1)
我相信您还必须编辑cpp文件以将两个函数嵌套到相应的命名空间中。另外,您必须选择要调用的函数,如namespace::function()
,或者可以将using namespace
与您创建的任一命名空间一起使用。希望这有帮助!
[更新#1]更容易混淆函数的声明和定义。请记住,您可以重新声明非成员函数。因此,如果头文件仅包含非成员函数声明,则可以在一个转换单元(cpp文件)中多次包含它。在头文件中添加ifndef
/ define
是避免潜在问题的好习惯,但这并不能解决您的问题。
你的问题是你想要有两个不同的函数定义,它们具有相同的函数签名(它的名称和参数),并且在C ++中是不允许的。您可以更改其中一个签名,也可以将它们放入不同的命名空间(您正在尝试但不触及其定义)。两种方式都要求您编辑包含其定义的文件。
[更新#2] 当您使用C代码更新问题时,我已经搜索并找到了这个:
What should I do if two libraries provide a function with the same name generating a conflict?
它肯定会帮助您更清楚地了解您的问题并找到解决方案。祝你好运!
答案 4 :(得分:1)
除了编辑.cpp文件本身并重命名函数(这不是一个实际的解决方案)之外,您的选项要么确保一次只包含一个具有重复功能的头文件(这可能是一个巨大的维护问题)或者,这是我的建议,使用名称空间。在这种情况下,它们可以为您节省大量的麻烦。
答案 5 :(得分:1)
您可能需要两件事之一。以下称为 Header Guard :
#ifndef MYHEADER_H
#define MYHEADER_H
//your header code goes here
#endif
这样,每个请求它的目标文件只包含一次标题。但是,如果您希望两个方法具有相同的标识符,则它们必须属于不同的命名空间:
namespace myspace1{
void func(void);
};
namespace myspace2{
void func(void);
};
除此之外,你可以做的其他事情并不多。你不应该有两个同名的功能一般。此外,您必须在您提到的头文件中修改它。
您可以根据需要随时声明功能,但只能有 ONE 定义。