LNK2005已定义在项目 [MSVC12] 中包含 C 类型头文件 C++错误
LNK2005 already defined error on inclusion of C-type header file in C++ project [MSVC12]
我在尝试将一些第三方代码集成到我的项目中时遇到了障碍。我正在尝试集成fontstash,这是一个仅标题的OpenGL文本渲染解决方案。(https://github.com/memononen/fontstash)总的来说,我也在使用SDL,GLEW,AssImp,Lua 5.3/LuaBridge和Bullet Physics。我已经将 fontstash 头文件放在我的 vc/include 目录中。编译正常进行,但链接在一个巨大的墙上惨遭失败......
c_main.obj : error LNK2005: "unsigned int __cdecl glfonsRGBA(unsigned char,unsigned char,unsigned char,unsigned char)" (?glfonsRGBA@@YAIEEEE@Z) already defined...
c_main.obj : error LNK2005: "void __cdecl glfonsDelete(struct FONScontext *)" (?glfonsDelete@@YAXPAUFONScontext@@@Z) already defined in...
...
c_main.obj : error LNK2005: _stbtt_FindMatchingFont already defined in...
c_main.obj : error LNK2005: _stbtt_GetFontNameString already defined...
它似乎只是简单地迭代通过 fontstash 头文件提供的整个函数列表。我尝试将标头包装在外部"C"{} 中,但无济于事。我也尝试包含项目目录中的文件。我不知道为什么会发生这种情况,以及从哪里开始弄清楚是什么导致了它。如主题标题所示,我正在使用MSVC12/Win7,并且我正在为Windows构建并为x86进行编译。
此外,我不止一次地包含这些文件,因为使用 fontstash 的相关代码在其他位置使用。我已经考虑过这是问题所在,但是来自fontstash的头文件具有包含保护,因此我不明白为什么会在这方面发生这种情况。
这是包含实现的头文件的常见问题。当您使用 #include
指令时,编译器只是插入.h
文件内容而不是它。因此,当您在项目的不同位置使用此标头时,您将获得其方法和全局变量的几个相同的实现。由于它具有#ifdef
或#pragma once
编译器保护,因此它可以很好地编译。但是,当链接器尝试将所有已编译obj
文件合并到一个可执行模块时,它会得到几个相同的实现。由于它不知道应该使用哪一个,因此您会收到LNK2005
错误。要解决此问题,您可以将实现和全局变量移动到单独的cpp
文件中,并将其包含在项目中。另一种方法是将所有标头函数标记为inline
,或使用__declspec(selectany)
- 包含的类类型显然没有声明,为什么?
- 表达式 SFINAE:如何根据类型是否包含具有一个或多个参数的函数来选择模板版本
- C++(和 ROS) - 包含与前向声明引用,设置默认值和类型定义
- C2011: 'Card':"类"类型重新定义(尽管使用了包含保护并且没有在文件中重新定义.cpp类)
- 包含它的模板化类型的shared_ptr
- C++如何乘以包含 std::variant 元素的向量的迭代器?正在执行迭代器类型的转换?
- C++包含函数标头会给出错误'__dest'未命名类型
- 何时包含内置类型和运算符的标头?
- 生成包含给定类型的 N 个参数的可变参数列表的最佳方法?
- 指针数据类型变量如何包含对象?
- 拒绝包含某些公共静态数据成员的类型
- 如何配置 Doxygen 以在"Class Index"中包含类的类型定义?
- 如何检查联合是否包含类型(使用 type_traits)?
- 如何创建一个包含三种不同类型的向量的向量
- 如何从包含基类指针的容器中调用派生类函数(基于其类型)?
- 包含可变参数包的第一个可转换类型的别名的结构
- 使用文件对话框选择包含特定文件类型的文件夹?
- 声明类型包含未展开的参数包'Args'
- "byte"数据类型包含奇怪的字符
- 在msvc中为uint8_t和类似类型包含或项目设置