You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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)

问题分析

  1. bgfx初始化顺序错误:bgfx::setPlatformData()必须在bgfx::init()之前调用,否则bgfx无法获取窗口上下文,直接导致初始化失败。
  2. 错误分支未终止程序: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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.07 23:35:37