我使用的是一个名为无核的标头专用库。这是一个只有头的库。当使用来自不同文件的多个包含时,我遇到了麻烦。它返回一个多定义示例:
...
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
#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
#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已经包含了头部保护,所以我不知道为什么会发生此错误。有什么建议吗?
发布于 2019-06-16 16:49:01
来自GitHub的自述机构:
该库包含在一个单独的头文件中,可以在标头模式下使用,也可以在实现模式中使用。默认情况下,只使用标头模式,并且允许将此标头包含在其他标头中,并且不包含实际的实现。 实现模式需要将预处理宏
NK_IMPLEMENTATION定义在一个.c/.cpp文件中,然后再对该文件进行#include处理,例如: #定义NK_IMPLEMENTATION #包括"nuklear.h“
因此,只有main.c和components.c中的一个应该包含#define NK_IMPLEMENTATION --但是您在这两个中都定义了它。
修复
#define NK_IMPLEMENTATION中删除components.c。nuklear.h之外,不要包含任何其他的Nuklear -指令不会告诉您这样做(至少在表面上是这样的;也许在其他地方有这么说的,但是…)。文件还指出:
重要:每次包含
"nuklear.h"时,都必须定义相同的可选标志。这是非常重要的,不这样做,要么导致编译器错误,甚至更糟的堆栈损坏。
拥有自己的头(例如use_nuklear.h )可能是值得的,不过我相信您会想到一个更好的名称,它包含正确的NK_*选项集(除了NK_IMPLEMENTATION)。然后在源文件中使用#include "use_nuklear.h"。这样,如果(当)您更改选项时,您只有一个位置可以更改-而重构将是一致的。
发布于 2019-06-16 16:14:02
您应该只在#define NK_SDL_GL3_IMPLEMENTATION之前的一个.c源文件中进行#include "nuklear_sdl_gl3.h"。
nuklear_sdl_gl3.h文件包含所有函数定义以及函数声明,您只希望将这些定义放在一个地方,或者,正如您发现的那样,您的链接器会抱怨。
发布于 2019-06-16 16:13:56
nuklear_sdl_gl3.h包含数据和函数。只是写得很糟糕。所有定义都应该在.c文件中,只有声明、类型定义、extern变量声明和静态内联函数应该在头文件中。
您不能在整个项目中不止一次地包含此文件。警卫在这里不工作,因为它包含在不同的编译单元中。
https://stackoverflow.com/questions/56620492
复制相似问题