C++ 链接错误..无效?

标签 c++ visual-studio-2010 linker

我不断收到此 Visual C++ 2010 LNK2005 链接器错误,说我对“Error.h”中包含的两个函数有多个定义。 (我为错误显示制作的标题)

我的项目是这样的:

BaseImage.h
BaseImage.cpp --> includes BaseImage.h , Error.h
PNGImage.h --> includes BaseImage.h
PNGImage.cpp --> includes PNGImage.h , Error.h
main.cpp --> includes PNGImage.h

当然还有 Error.h:

/*
Optional macros:
AE_EXIT_AT_ERROR
*/
#pragma once
#include <stdexcept>

void aeError(const char *str, int code=1)
{
    throw std::runtime_error(str);
    #ifdef AE_EXIT_AT_ERROR
    std::exit(code);
    #endif
}

void aeAssert(bool b, const char *failStr = "assertion failed")
{
    if(!b)
        aeError(failStr);
}

我在每个头文件中都有#pragma once,我也尝试向 Error.h 添加 include guards。

这是编译输出:

1>PNGImage.obj : error LNK2005: "void __cdecl aeError(char const *,int)" (?aeError@@YAXPBDH@Z) already defined in BaseImage.obj
1>PNGImage.obj : error LNK2005: "void __cdecl aeAssert(bool,char const *)" (?aeAssert@@YAX_NPBD@Z) already defined in BaseImage.obj
1>C:\...\Project.exe : fatal error LNK1169: one or more multiply defined symbols found

这可能是一个错误吗?

最佳答案

当您在 .h 文件中定义函数时,将它们设为内联。否则,函数定义是所有 #include 它的目标代码的一部分,具有外部链接。

inline void aeError(const char *str, int code=1)
{
    throw std::runtime_error(str);
    #ifdef AE_EXIT_AT_ERROR
    std::exit(code);
    #endif
}

inline void aeAssert(bool b, const char *failStr = "assertion failed")
{
    if(!b)
        aeError(failStr);
}

另一种选择是在 .h 文件中声明函数并在一个 .cpp 文件中定义它们。

.h 文件:

extern void aeError(const char *str, int code=1);

extern void aeAssert(bool b, const char *failStr = "assertion failed");

.cpp 文件:

// Don't use inline and don't include the default argument values.

void aeError(const char *str, int code)
{
    throw std::runtime_error(str);
    #ifdef AE_EXIT_AT_ERROR
    std::exit(code);
    #endif
}

void aeAssert(bool b, const char *failStr)
{
    if(!b)
        aeError(failStr);
}

关于C++ 链接错误..无效?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28662268/

相关文章:

java - Cap'n Proto - 在 Java 中查找消息大小

c++ - AttachConsole 和 QProcess::readAll()

c - 如何在Ubuntu上编译ELSD?链接错误

c++ - 如何在自定义 DirectShow 过滤器中以秒为单位获得正确的帧时间?

c++ - 使用 C++ 和 WinAPI 在 Windows 8 上登录用户名或电子邮件

visual-studio-2010 - 对象浏览器设置中缺少查看派生类型选项

c++ - 如何有效地重用映射值

visual-studio - Microsoft Visual Studio 2010 学术版

r - 如何强制 ld 链接到静态库

c - 为什么在从没有任何目标文件的静态库创建 EXE 时需要手动链接 C 运行时库?