DebugUtil.h
#ifndef DEBUG_UTIL_H
#define DEBUG_UTIL_H
#include <windows.h>
int DebugMessage(const char* message)
{
const int MAX_CHARS = 1023;
static char s_buffer[MAX_CHARS+1];
return 0;
}
#endif
当我尝试运行时,我收到此错误:
Terrain.obj:错误LNK2005:“int __cdecl DebugMessage(char const *)“(?DebugMessage @@ YAHPBD @ Z)已经 在Loodus.obj中定义
Renderer.obj:错误LNK2005:“int __cdecl DebugMessage(char const *)“(?DebugMessage @@ YAHPBD @ Z)已经 在Loodus.obj中定义
test.obj:错误LNK2005:“int __cdecl DebugMessage(char const *)“ (?DebugMessage @@ YAHPBD @ Z)已经 在Loodus.obj中定义
C:\用户\蒂亚戈\桌面\ Loodus Engine \ Debug \ Loodus Engine.exe:致命 错误LNK1169:一次或多次乘法 找到已定义的符号
但为什么会这样呢?我在标题中有#ifndef #define和#endif,因此不应该发生多个定义
答案 0 :(得分:61)
将定义(正文)放在cpp文件中,只将声明留在h文件中。包含警卫仅在一个翻译单元(也就是源文件)内运行,而不是在所有程序中运行。
C ++标准的一个定义规则规定,在程序中使用的每个非内联函数应该只出现一个定义。因此,另一种选择是使您的函数内联。
答案 1 :(得分:9)
使函数内联或在头文件中声明函数并在cpp文件中定义它。
inline int DebugMessage(const char* message)
{
const int MAX_CHARS = 1023;
static char s_buffer[MAX_CHARS+1];
return 0;
}
编辑:
正如Tomalak Geret'kal的评论所暗示的那样,使用我后面的建议比使用前者更好,并将函数的声明移到cpp文件中。
答案 2 :(得分:6)
(假设发布的代码是一个标题,包含在多个.cpp文件中)
标头保护不会保护您免受链接时多重定义的影响。无论您是否确保每个翻译单元只显示一次标题,如果您有多个翻译单元,那么这仍然是多个定义。
在源文件中编写定义,在标题中只写声明。
唯一的例外是inline
函数,在class
定义中定义的函数(虽然不建议这样做!)和函数模板。
答案 3 :(得分:3)
此功能包含在每个翻译单元中,因此您可以获得多个定义 - 每个.obj文件都包含自己的副本。当它们将它们全部链接在一起时,链接器正确地显示了上述错误。
你可以做一些事情:
答案 4 :(得分:0)
将定义移动到.cpp文件。
答案 5 :(得分:0)
在C ++文件中声明您的函数。由于您在头文件中定义了函数,并且该头文件包含在多个源文件中,因此会为包含它的每个源文件定义它。这就是为什么它被报道为在多个地方被定义的原因。
或者,您可以将其设置为内联,以便将代码插入到任何位置,而不是每次都定义为单独的函数。
答案 6 :(得分:0)
看起来您将DebugUtil.h包含在多个转换单元中,然后将这些对象链接在一起。但是,DebugUtil.h提供了DebugMessage函数的定义,因此该定义存在于包含标头的所有转换单元中。因此,当您链接对象时,链接器会正确地抱怨符号是多重定义的。
更改DebugUtil.h,使其通过原型声明DebugMessage,但不提供定义,并将DebugMessage的定义放在.c文件中,您将编译该文件并与其他对象链接。
答案 7 :(得分:0)
这只能防止同一源文件中出现多个包含内容;多个源文件#include
仍将生成DebugMessage()
的多个定义。一般情况下,您应该根本不将函数放在头文件中,或者将它们设为static
(通常是inline
,否则通常不会有多个static
定义相同的功能)。
答案 8 :(得分:0)
100%确定您是否正确包含了警卫,但仍然出现重新定义错误?
对于Visual Studio: 我真的很沮丧,因为我被正确包括在内, 只是找出问题是视觉工作室。如果您已添加该文件 对于您的项目,编译器将添加文件两次,即使您有 包括实施文件和头文件的保护。
如果你不单独使用visual studio,并说...有时使用code :: blocks,你可能只想在检测到缺少visual studio环境时#include文件。
DebugUtil.h :
----------------------
#ifndef _WIN32
#include "DebugUtil.c"
#endif
----------------------
如果你可以包括stdio.h, 你可以对它不那么讨厌:
DebugUtil.h :
----------------------
#include <stdio.h>
#ifdef _MSC_VER
#include "DebugUtil.c"
#endif
----------------------
参考: 预定义的宏,Visual Studio: https://msdn.microsoft.com/en-us/library/b0084kay.aspx