类中调用OpenGL函数触发段错误(Segfault):glCreateProgram崩溃但主函数调用正常的问题排查
类中调用OpenGL函数触发段错误(Segfault):glCreateProgram崩溃但主函数调用正常的问题排查
看起来你遇到的问题核心是OpenGL函数指针的加载范围冲突,以及GLAD和GLEW混用导致的函数定义不一致,咱们一步步拆解解决:
问题根源分析
从你的最小可复现示例里能发现几个关键问题:
- 你的
Shader.cpp里包含了<GL/glew.h>,但主函数用的是GLAD——这两个都是OpenGL函数加载库,绝对不能同时使用,它们会争夺OpenGL函数指针的控制权,直接导致未定义行为。 - 你的
minReproduce.hpp里包含的是系统原生的<GL/gl.h>,而非GLAD生成的glad/glad.h。系统gl.h只声明OpenGL函数原型,不提供实际的函数指针实现;GLAD加载后,所有OpenGL函数都是通过它初始化的指针调用的,如果编译单元(比如Shader的cpp文件)没包含GLAD头文件,编译器会把glCreateProgram解析成未定义的函数符号,运行时就会因指针未初始化触发段错误。
具体修复步骤
1. 彻底移除GLEW依赖
- 删除所有代码中的
<GL/glew.h>包含语句 - 编译时去掉
-lGLEW链接选项,修改后的编译命令如下:g++ -c minReproduce.cpp -o min.o gcc -c glad.c -o glad.o g++ -c main.cpp -o main.o g++ -o minReprod main.o glad.o min.o -lGL -lglfw
2. 确保所有OpenGL相关代码都包含GLAD头文件
修改minReproduce.hpp,把系统gl.h替换为GLAD的头文件:
#ifndef MINREPRODUCE_HPP #define MINREPRODUCE_HPP #include <glad/glad.h> // 必须在任何OpenGL代码前包含,替换系统原生gl.h class Shader{ public: Shader(); private: GLuint program{}; }; #endif
同时修改Shader.cpp,移除GLEW包含,确保间接引入GLAD:
#include "minReproduce.hpp" // 已包含glad.h Shader::Shader(){ this->program = glCreateProgram(); }
3. 确认上下文初始化逻辑
你的主函数里的上下文流程是正确的:先创建窗口→调用glfwMakeContextCurrent(window)→加载GLAD。只要确保所有OpenGL函数调用都在GLAD加载之后发生(你的代码里Shader shader1{};是在GLAD加载后创建的,这没问题),上下文就是当前的,完全不需要额外传递上下文。
补充说明
为什么主函数里直接调用glCreateProgram没问题?因为主函数包含了glad/glad.h,编译器会把调用解析为GLAD初始化后的有效函数指针;而Shader类的编译单元因为用了系统gl.h或GLEW,导致函数指针未正确绑定,才会崩溃。
内容来源于stack exchange
相关产品推荐
相关产品推荐

