I've been working on a static library to streamline two-dimensional rendering in OpenGL. The library is built using the glew and OpenGL libraries, and the other specifics are unimportant for this question because the error comes from executables that link with the library rather than the library itself.
After the executable which links with the library is run, the program crashes on the first call to an OpenGL function that is not included in Windows' stripped down OpenGL implementation (I.E. the functions defined by glew). This behavior is only observed when building the program for x64 Release. When building for x64 Debug, everything runs as expected.
The error it gives is the following:
Exception Thrown
Exception thrown at 0x0000000000000000 in ExampleHelloWorld.exe: 0xC0000005: Access violation executing location 0x0000000000000000.
I'm compiling using Microsoft Visual Studio 2022's cross-platform CMake project type.
Below I've included a stripped-down example of the build which exhibits the same problems:
CMakeLists.txt:
cmake_minimum_required (VERSION 3.15)
project("ReproducingOpenGLErrors")
set(CMAKE_C_STANDARD 11)
set(CMAKE_C_STANDARD_REQUIRED true)
set(glew_DIR "${CMAKE_CURRENT_LIST_DIR}/cmake")
find_package(glew REQUIRED)
find_package(OpenGL REQUIRED)
# -----LIBRARY BUILD-----
add_library(ReproducingOpenGLErrors STATIC Library.c)
target_include_directories(ReproducingOpenGLErrors PUBLIC Library.h ${glew_INCLUDE_DIRS} OpenGL::GL OpenGL::GLU)
# -----EXAMPLE BUILD-----
set(glfw3_DIR "${CMAKE_CURRENT_LIST_DIR}/cmake")
find_package(glfw3 REQUIRED)
add_executable(ExampleHelloWorld Main.c)
target_include_directories(ExampleHelloWorld PUBLIC ${glew_INCLUDE_DIRS} ${glfw3_INCLUDE_DIRS} OpenGL::GL OpenGL::GLU)
target_link_libraries(ExampleHelloWorld ${glew_LIBRARIES} ${glfw3_LIBRARIES} ReproducingOpenGLErrors ${OPENGL_LIBRARIES})
glew-config.cmake:
set(glew_INCLUDE_DIRS "${PROJECT_SOURCE_DIR}/include")
if (${CMAKE_SIZEOF_VOID_P} MATCHES 8)
set(glew_LIBRARIES "${PROJECT_SOURCE_DIR}/lib/glew32s.lib")
endif ()
string(STRIP "${glew_LIBRARIES}" glew_LIBRARIES)
glfw3-config.cmake:
set(glfw3_INCLUDE_DIRS "${PROJECT_SOURCE_DIR}/include")
if (${CMAKE_SIZEOF_VOID_P} MATCHES 8)
set(glfw3_LIBRARIES "${PROJECT_SOURCE_DIR}/lib/glfw3_mt.lib")
endif ()
string(STRIP "${glfw3_LIBRARIES}" glfw3_LIBRARIES)
Library.h:
#ifndef LIBRARY_H
#define LIBRARY_H
#ifdef __cplusplus
extern "C" {
#endif
#define GLEW_STATIC
#include "glew.h"
#include <gl/GL.h>
#include <gl/GLU.h>
GLuint CreateVertexShader(void);
#ifdef __cplusplus
}
#endif
#endif
Library.c:
#include "Library.h"
GLuint CreateVertexShader(void) { return glCreateShader(GL_VERTEX_SHADER); }
Main.c:
#include "Library.h"
#include "glfw3.h"
#include <assert.h>
int main(int argc, char** argv)
{
assert(glfwInit());
GLFWwindow* window = glfwCreateWindow(800, 600, "Hello World", NULL, NULL);
assert(window != NULL);
glfwMakeContextCurrent(window);
assert(glewInit() == GLEW_OK);
GLuint newShader = CreateVertexShader();
return 0;
}
My apologies for its lengthy nature, I tried to trim it down as much as I could, but graphics programming is inherently long-winded. Needless to say, I'm pretty stumped.
Most of the things I've tried have been either superfluous or incorrect, but I'll give a summary of what I've done:
- Ensured all pointers are not null before being de-referenced
- Checked that all variable declarations are explicitly initialized
- Built the library with the c calling convention
- Tried linking [ReproducingOpenGLErrors] with glew