首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >只包含头库的多个包含导致重新定义错误

只包含头库的多个包含导致重新定义错误
EN

Stack Overflow用户
提问于 2019-06-16 16:02:24
回答 3查看 589关注 0票数 1

我使用的是一个名为无核的标头专用库。这是一个只有头的库。当使用来自不同文件的多个包含时,我遇到了麻烦。它返回一个多定义示例:

代码语言:javascript
复制
...
obj/main.o:main.c:(.text+0x4a52b): multiple definition of `nk_sdl_font_stash_begin'
obj/components.o:components.c:(.text+0x4a56f): first defined here
obj/main.o:main.c:(.text+0x4a563): multiple definition of `nk_sdl_font_stash_end'
obj/components.o:components.c:(.text+0x4a5a7): first defined here
obj/main.o:main.c:(.text+0x4a5f4): multiple definition of `nk_sdl_handle_event'
obj/components.o:components.c:(.text+0x4a638): first defined here
obj/main.o:main.c:(.text+0x4ac9f): multiple definition of `nk_sdl_shutdown'
obj/components.o:components.c:(.text+0x4ace3): first defined here

我正在尝试将库包含到两个文件中。

main.c

代码语言:javascript
复制
#define SDL_MAIN_HANDLED
#include <GL/glew.h>
#include <SDL2/SDL.h>
#include <SDL2/SDL_opengl.h>

#define NK_INCLUDE_FIXED_TYPES
#define NK_INCLUDE_STANDARD_IO
#define NK_INCLUDE_STANDARD_VARARGS
#define NK_INCLUDE_DEFAULT_ALLOCATOR
#define NK_INCLUDE_VERTEX_BUFFER_OUTPUT
#define NK_INCLUDE_FONT_BAKING
#define NK_INCLUDE_DEFAULT_FONT
#define NK_IMPLEMENTATION
#define NK_SDL_GL3_IMPLEMENTATION
#include "nuklear.h"
#include "nuklear_sdl_gl3.h"
#include "components.h"
...

组件c

代码语言:javascript
复制
#define SDL_MAIN_HANDLED
#include <GL/glew.h>
#include <SDL2/SDL.h>
#include <SDL2/SDL_opengl.h>

#define NK_INCLUDE_FIXED_TYPES
#define NK_INCLUDE_STANDARD_IO
#define NK_INCLUDE_STANDARD_VARARGS
#define NK_INCLUDE_DEFAULT_ALLOCATOR
#define NK_INCLUDE_VERTEX_BUFFER_OUTPUT
#define NK_INCLUDE_FONT_BAKING
#define NK_INCLUDE_DEFAULT_FONT
#define NK_IMPLEMENTATION
#define NK_SDL_GL3_IMPLEMENTATION
#include "nuklear.h"
#include "nuklear_sdl_gl3.h"

Nuklear已经包含了头部保护,所以我不知道为什么会发生此错误。有什么建议吗?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2019-06-16 16:49:01

来自GitHub的自述机构:

该库包含在一个单独的头文件中,可以在标头模式下使用,也可以在实现模式中使用。默认情况下,只使用标头模式,并且允许将此标头包含在其他标头中,并且不包含实际的实现。 实现模式需要将预处理宏NK_IMPLEMENTATION定义在一个.c/.cpp文件中,然后再对该文件进行#include处理,例如: #定义NK_IMPLEMENTATION #包括"nuklear.h“

因此,只有main.ccomponents.c中的一个应该包含#define NK_IMPLEMENTATION --但是您在这两个中都定义了它。

修复

  • #define NK_IMPLEMENTATION中删除components.c
  • 除了nuklear.h之外,不要包含任何其他的Nuklear -指令不会告诉您这样做(至少在表面上是这样的;也许在其他地方有这么说的,但是…)。

文件还指出:

重要:每次包含"nuklear.h"时,都必须定义相同的可选标志。这是非常重要的,不这样做,要么导致编译器错误,甚至更糟的堆栈损坏。

拥有自己的头(例如use_nuklear.h )可能是值得的,不过我相信您会想到一个更好的名称,它包含正确的NK_*选项集(除了NK_IMPLEMENTATION)。然后在源文件中使用#include "use_nuklear.h"。这样,如果(当)您更改选项时,您只有一个位置可以更改-而重构将是一致的。

票数 7
EN

Stack Overflow用户

发布于 2019-06-16 16:14:02

您应该只在#define NK_SDL_GL3_IMPLEMENTATION之前的一个.c源文件中进行#include "nuklear_sdl_gl3.h"

nuklear_sdl_gl3.h文件包含所有函数定义以及函数声明,您只希望将这些定义放在一个地方,或者,正如您发现的那样,您的链接器会抱怨。

票数 3
EN

Stack Overflow用户

发布于 2019-06-16 16:13:56

nuklear_sdl_gl3.h包含数据和函数。只是写得很糟糕。所有定义都应该在.c文件中,只有声明、类型定义、extern变量声明和静态内联函数应该在头文件中。

您不能在整个项目中不止一次地包含此文件。警卫在这里不工作,因为它包含在不同的编译单元中。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/56620492

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档