GLFW初始化正常但整合bgfx时启动失败并触发段错误求助
问题与解决方案
问题背景
代码编译正常,但运行时触发bgfx初始化失败、GLFW未初始化错误,最终出现段错误。仅保留GLFW相关代码时程序可正常运行,替换为SDL2后问题依旧。环境为Linux Ubuntu 22.04.3 LTS,GLFW和bgfx通过vcpkg安装,使用Makefile构建。
原始代码
#define WDW_WIDTH 1280 #define WDW_HEIGHT 720 #define GLFW_INCLUDE_NONE #if defined (_WIN32) #define GLFW_EXPOSE_NATIVE_WIN32 #elif defined (__linux__) #define GLFW_EXPOSE_NATIVE_X11 #elif defined (__APPLE__) #define GLFW_EXPOSE_NATIVE_COCOA #endif #include <iostream> #include <GLFW/glfw3.h> #include <GLFW/glfw3native.h> #include <bgfx/bgfx.h> #include <bgfx/platform.h> auto GetNativeWindow(GLFWwindow* window) { #if defined (GLFW_EXPOSE_NATIVE_WIN32) return glfwGetWin32Window(window); #elif defined (GLFW_EXPOSE_NATIVE_X11) return (void*)(uintptr_t)glfwGetX11Window(window); #elif defined (GLFW_EXPOSE_NATIVE_COCOA) return glfwGetCocoaWindow(window); #else std::cout << "undefined platform\n"; #endif } #if defined(GLFW_EXPOSE_NATIVE_X11) Display* GetNativeDisplay() { return glfwGetX11Display(); } #else int* GetNativeDisplay() { return NULL; } #endif static void error_callback(int error, const char* description) { std::cout << "Error [" << error << "] : " << description << "\n"; } int main() { glfwSetErrorCallback(error_callback); if (!glfwInit()) { error_callback(1, "failed to init glfw"); glfwTerminate(); } GLFWwindow* window = glfwCreateWindow(WDW_WIDTH, WDW_HEIGHT, "GAME", nullptr, nullptr); if (window == nullptr) { error_callback(2, "failed to create window"); glfwTerminate(); } glfwMakeContextCurrent(window); bgfx::Init bgfx_init; bgfx_init.type = bgfx::RendererType::Count; // Automatically choose a renderer. bgfx_init.vendorId = BGFX_PCI_ID_NONE; bgfx_init.resolution.width = WDW_WIDTH; bgfx_init.resolution.height = WDW_HEIGHT; bgfx_init.resolution.reset = BGFX_RESET_VSYNC; if (!bgfx::init(bgfx_init)) { error_callback(1, "failed to init bgfx"); glfwTerminate(); } bgfx::PlatformData pd; pd.ndt = GetNativeDisplay(); pd.nwh = GetNativeWindow(window); bgfx::setPlatformData(pd); bgfx::setViewClear(0, BGFX_CLEAR_COLOR | BGFX_CLEAR_DEPTH, 0x443355FF, 1.0f, 0); bgfx::setViewRect(0, 0, 0, WDW_WIDTH, WDW_HEIGHT); while (!glfwWindowShouldClose(window)) { bgfx::frame(); glfwPollEvents(); } bgfx::shutdown(); glfwDestroyWindow(window); glfwTerminate(); return 0; }
错误信息
Error [1] : failed to init bgfx Error [65537] : The GLFW library is not initialized Error [65537] : The GLFW library is not initialized Segmentation fault (core dumped)
问题分析
- bgfx初始化顺序错误:
bgfx::setPlatformData()必须在bgfx::init()之前调用,否则bgfx无法获取窗口上下文,直接导致初始化失败。 - 错误分支未终止程序:bgfx初始化失败后调用
glfwTerminate()但未退出程序,后续代码继续执行glfwPollEvents()等依赖GLFW的操作,此时GLFW已被终止,触发“未初始化”错误,最终引发段错误。
修复方案
调整bgfx初始化流程,提前设置平台数据,并在错误分支直接退出程序:
修复后代码
#define WDW_WIDTH 1280 #define WDW_HEIGHT 720 #define GLFW_INCLUDE_NONE #if defined (_WIN32) #define GLFW_EXPOSE_NATIVE_WIN32 #elif defined (__linux__) #define GLFW_EXPOSE_NATIVE_X11 #elif defined (__APPLE__) #define GLFW_EXPOSE_NATIVE_COCOA #endif #include <iostream> #include <cstdlib> #include <GLFW/glfw3.h> #include <GLFW/glfw3native.h> #include <bgfx/bgfx.h> #include <bgfx/platform.h> auto GetNativeWindow(GLFWwindow* window) { #if defined (GLFW_EXPOSE_NATIVE_WIN32) return glfwGetWin32Window(window); #elif defined (GLFW_EXPOSE_NATIVE_X11) return (void*)(uintptr_t)glfwGetX11Window(window); #elif defined (GLFW_EXPOSE_NATIVE_COCOA) return glfwGetCocoaWindow(window); #else std::cerr << "undefined platform\n"; return nullptr; #endif } #if defined(GLFW_EXPOSE_NATIVE_X11) Display* GetNativeDisplay() { return glfwGetX11Display(); } #else void* GetNativeDisplay() { return nullptr; } #endif static void error_callback(int error, const char* description) { std::cerr << "Error [" << error << "] : " << description << "\n"; } int main() { glfwSetErrorCallback(error_callback); if (!glfwInit()) { error_callback(1, "failed to init glfw"); return EXIT_FAILURE; } GLFWwindow* window = glfwCreateWindow(WDW_WIDTH, WDW_HEIGHT, "GAME", nullptr, nullptr); if (!window) { error_callback(2, "failed to create window"); glfwTerminate(); return EXIT_FAILURE; } // 提前设置bgfx平台数据,必须在init之前调用 bgfx::PlatformData pd; pd.ndt = GetNativeDisplay(); pd.nwh = GetNativeWindow(window); bgfx::setPlatformData(pd); bgfx::Init bgfx_init; bgfx_init.type = bgfx::RendererType::Count; // 自动选择渲染器 bgfx_init.vendorId = BGFX_PCI_ID_NONE; bgfx_init.resolution.width = WDW_WIDTH; bgfx_init.resolution.height = WDW_HEIGHT; bgfx_init.resolution.reset = BGFX_RESET_VSYNC; if (!bgfx::init(bgfx_init)) { error_callback(1, "failed to init bgfx"); glfwDestroyWindow(window); glfwTerminate(); return EXIT_FAILURE; } bgfx::setViewClear(0, BGFX_CLEAR_COLOR | BGFX_CLEAR_DEPTH, 0x443355FF, 1.0f, 0); bgfx::setViewRect(0, 0, 0, WDW_WIDTH, WDW_HEIGHT); while (!glfwWindowShouldClose(window)) { bgfx::frame(); glfwPollEvents(); } bgfx::shutdown(); glfwDestroyWindow(window); glfwTerminate(); return EXIT_SUCCESS; }
额外注意事项
- 确保vcpkg安装的bgfx与GLFW版本兼容,Ubuntu 22.04下建议使用最新稳定版。
- Makefile中需正确链接依赖库,示例链接参数:
-lbgfx -lglfw -lX11 -lGL -lm
内容的提问来源于stack exchange,提问作者Mii Gel
相关产品推荐
相关产品推荐

