我尝试在项目中集成某些第三方代码时遇到了障碍。我正在尝试集成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的提供的头文件有包含警卫,所以我不明白为什么会出现这种情况。
答案 0 :(得分:1)
这是头文件的常见问题,包含实现。使用#include
指令时,编译器只需插入.h
文件内容而不是它。因此,当您在项目的不同位置使用此标头时,您将获得其方法和全局变量的几个相同实现。由于它有#ifdef
或#pragma once
编译器保护,它编译得很好。但是当链接器尝试将所有已编译的obj
文件统一到一个可执行模块时,它会获得几个相同的实现。由于无法知道应该使用哪一个,因此会出现LNK2005
错误。要解决此问题,您可以将实现和全局变量移动到单独的cpp
文件中,并将其包含在项目中。其他方法是将所有标题函数标记为inline
,或使用__declspec(selectany)