抛出OpenGL异常:读取访问冲突,窗口为0xCCCCCCCC

时间:2018-01-28 05:59:38

标签: c windows exception opengl

我使用的是我在上一个问题中描述的相同框架。

我通过创建一个新的dll而不是仅仅从Windows应用程序(.exe)'更改项目的构建类型来解决它。到' DLL(.dll)'。

但现在我在我的结构中使用GLFWwindow *类型的变量并尝试写入或读取。它总是导致分别弹出写访问或读访问冲突。异常突然出现,就像窗口开始然后关闭一样,显示异常。

例外说明如下: -

抛出异常:读取访问冲突 窗口是0xCCCCCCCC。

它发生在GLFW的window.c文件中,它指向尝试读取它的函数。我甚至尝试使用指针来修改窗口,但它仍然没有用。

以下是框架的代码: - 已修改!

window.h中

#ifndef LIB_GRAPHICS
#define LIB_GRAPHICS

#ifdef LIB_EXPORTS
#define LIB_EXPORT _declspec(dllexport)
#else
#define LIB_EXPORT _declspec(dllimport)
#endif

#define LIB_FALSE 0
#define LIB_TRUE 1

#define LIB_BeginRender LIB_SetEvents(); LIB_ClearToColor
#define LIB_EndRender LIB_SwapWindowBuffers

#define LIB_CENTER_POSITION 0xCEAAFFEE

/* Define other things... */

typedef const char* LIB_String;
typedef unsigned LIB_Integer;
typedef char LIB_Char;
typedef int LIB_Bool;

/* Define the structures... */

typedef struct LIB_Window LIB_Window;

typedef struct LIB_Color
{
    int r;
    int g;
    int b;
    int a;
} LIB_Color;

/* Constructors, destructors and other functions... */

LIB_Bool LIB_EXPORT LIB_Initialize();
void LIB_EXPORT LIB_SetEvents();
void LIB_EXPORT LIB_ClearToColor(const LIB_Color color);
void LIB_EXPORT LIB_SetFrameColor(const LIB_Color color);


LIB_EXPORT LIB_Window* LIB_CreateWindow(const LIB_String title, const int x, const int y, const int width, const int height, const LIB_Bool resizable, const LIB_Bool fullscreen);
void LIB_EXPORT LIB_GetDisplaySize(int *width, int *height);

void LIB_EXPORT LIB_GetWindowFrameSize(LIB_Window* window, int *width, int *height);
void LIB_EXPORT LIB_GetWindowCursorPosition(LIB_Window* window, float *x, float *y);

void LIB_EXPORT LIB_GetWindowPosition(LIB_Window* window, int *x, int *y);
void LIB_EXPORT LIB_GetWindowSize(LIB_Window* window, int *width, int *height);
LIB_String LIB_EXPORT LIB_GetWindowTitle(LIB_Window* window);
LIB_Bool LIB_EXPORT LIB_IsWindowFullScreen(LIB_Window* window);
LIB_Bool LIB_EXPORT LIB_IsWindowOpened(LIB_Window* window);
void LIB_EXPORT LIB_SwapWindowBuffers(LIB_Window* window);

void LIB_EXPORT LIB_SetWindowPosition(LIB_Window* window, const int x, const int y);
void LIB_EXPORT LIB_SetWindowSize(LIB_Window* window, const int width, const int height);
void LIB_EXPORT LIB_SetWindowTitle(LIB_Window * window, const LIB_String title);
void LIB_EXPORT LIB_SetFullScreenState(LIB_Window * window, const LIB_Bool fullscreen);

void LIB_EXPORT LIB_DestroyWindow(LIB_Window* window);


void LIB_EXPORT LIB_Terminate();

#endif /* LIB_GRAPHICS */

window.c

#include "window.h"
#define GLEW_STATIC
#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include <stdio.h>
#include <stdlib.h>

/* Create the structures... */
struct LIB_Window
{
    LIB_String title;
    int x;
    int y;
    int width;
    int height;
    LIB_Bool fullscreen;
    GLFWwindow** window;
};

/* Start the functions here... */
LIB_Bool LIB_Initialize()
{
    return (LIB_Bool)glfwInit();
}

void LIB_SetEvents()
{
    glfwPollEvents();
}

void LIB_ClearToColor(const LIB_Color color)
{
    glClearColor((float)color.r / 255, (float)color.g / 255, (float)color.b / 255, (float)color.a / 255);
    glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
}

void LIB_SetFrameColor(const LIB_Color color)
{
    glClearColor((float)color.r / 255, (float)color.g / 255, (float)color.b / 255, (float)color.a / 255);
}

LIB_Window* LIB_CreateWindow(const LIB_String title, int x, int y, const int width, const int height, const LIB_Bool resizable, const LIB_Bool fullscreen)
{
    LIB_Window wind;
    wind.title = title;
    if (x == LIB_CENTER_POSITION)
    {
        const GLFWvidmode* mode = glfwGetVideoMode(glfwGetPrimaryMonitor());
        x = (mode->width - width) / 2;
    }
    wind.x = x;
    if (y == LIB_CENTER_POSITION)
    {
        const GLFWvidmode* mode = glfwGetVideoMode(glfwGetPrimaryMonitor());
        y = (mode->height - height) / 2;
    }
    wind.y = y;
    wind.width = width;
    wind.height = height;
    wind.fullscreen = fullscreen;

    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
    glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
    glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GLFW_TRUE);
    glfwWindowHint(GLFW_RESIZABLE, resizable);

    wind.window = NULL;
    if (fullscreen == 1)
    {
        wind.window = (GLFWwindow**)glfwCreateWindow(width, height, title, glfwGetPrimaryMonitor(), NULL);
    }
    else if (fullscreen == 0)
    {
        wind.window = (GLFWwindow**)glfwCreateWindow(width, height, title, NULL, NULL);
    }

    glfwSetWindowPos((GLFWwindow*)wind.window, x, y);

    int screen_width, screen_height;
    glfwGetFramebufferSize((GLFWwindow*)wind.window, &screen_width, &screen_height);

    if (wind.window == NULL)
    {
        glfwTerminate();
        return NULL;
    }

    glfwMakeContextCurrent((GLFWwindow*)wind.window);
    glewExperimental = GL_TRUE;

    if (glewInit() != GLEW_OK)
    {
        return NULL;
    }

    glViewport(0, 0, screen_width, screen_height);
    glMatrixMode(GL_PROJECTION);
    glPushMatrix();
    glLoadIdentity();
    glMatrixMode(GL_MODELVIEW);
    glEnable(GL_BLEND);
    glEnable(GL_ALPHA_TEST);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    return &wind;
}

void LIB_GetWindowFrameSize(LIB_Window * window, int *width, int *height)
{
    int screenwidth, screenheight;
    glfwGetFramebufferSize(((GLFWwindow*)window->window), &screenwidth, &screenheight);
    *width = screenwidth;
    *height = screenheight;
}

void LIB_GetWindowCursorPosition(LIB_Window * window, float *x, float *y)
{
    double cx, cy;
    glfwGetCursorPos(((GLFWwindow*)window->window), &cx, &cy);
    *x = (float)cx;
    *y = (float)cy;
}

void LIB_GetDisplaySize(int *width, int *height)
{
    const struct GLFWvidmode* mode = glfwGetVideoMode(glfwGetPrimaryMonitor());
    *width = mode->width;
    *height = mode->height;
}

void LIB_GetWindowPosition(LIB_Window * window, int *x, int *y)
{
    *x = (window)->x;
    *y = (window)->y;
}

void LIB_GetWindowSize(LIB_Window * window, int *width, int *height)
{
    *width = (window)->width;
    *height = (window)->height;
}

LIB_String LIB_GetWindowTitle(LIB_Window * window)
{
    return (window)->title;
}

LIB_Bool LIB_IsWindowFullScreen(LIB_Window * window)
{
    return (window)->fullscreen;
}

LIB_Bool LIB_IsWindowOpened(LIB_Window * window)
{
    return !glfwWindowShouldClose(((GLFWwindow*)window->window));
}

void LIB_SwapWindowBuffers(LIB_Window * window)
{
    glfwSwapBuffers(((GLFWwindow*)window->window));
}

void LIB_SetWindowPosition(LIB_Window * window, const int x, const int y)
{
    glfwSetWindowPos(((GLFWwindow*)window->window), x,y);
    (window)->x = x;
    (window)->y = y;
}

void LIB_SetWindowSize(LIB_Window * window, const int width, const int height)
{
    glfwSetWindowSize(((GLFWwindow*)window->window), width, height);
    (window)->width = width;
    (window)->height = height;
}

void LIB_SetWindowTitle(LIB_Window * window, const LIB_String title)
{
    glfwSetWindowTitle(((GLFWwindow*)window->window), title);
    (window)->title = title;
}

void LIB_SetFullScreenState(LIB_Window * window, const LIB_Bool fullscreen)
{
    const GLFWvidmode* mode = glfwGetVideoMode(glfwGetPrimaryMonitor());
    if (fullscreen == LIB_FALSE)
    {
        glfwSetWindowMonitor(((GLFWwindow*)window->window), NULL, (window)->x, (window)->y, (window)->width, (window)->height, 60);
    }
    else if (fullscreen == LIB_TRUE)
    {
        glfwSetWindowMonitor(((GLFWwindow*)window->window), glfwGetPrimaryMonitor(), 0, 0, mode->width, mode->height, 60);
    }
    (window)->fullscreen = fullscreen;
}

void LIB_DestroyWindow(LIB_Window * window)
{
    (window)->window = NULL;
    (window)->title = NULL;
    (window)->x = 0;
    (window)->y = 0;
    (window)->width = 0;
    (window)->height = 0;
    free(window);
}

void LIB_Terminate()
{
    printf("BLITZ terminated by the user!!\n");
    glfwTerminate();
}

1 个答案:

答案 0 :(得分:0)

函数LIB_CreateWindow返回指向loacal变量LIB_Window wind;的指针。函数终止后,变量超出范围,指针指向&#34;无处&#34;。这是一种未定义的行为。注意,函数中的局部变量在堆栈上分配,当函数终止时,它立即被释放。

您可以通过声明变量static

来快速解决此问题
static LIB_Window wind;

但是,如果你这样做,那么当然库只能管理一个窗口。

您可以创建动态分配的变量

void LIB_CreateWindow( ..... )
{
    .....    

    LIB_Window *newWnd = malloc( sizeof(LIB_Window) );
    *newWnd = wind;
    return newWnd;
}

或者在函数外部声明类型为LIB_Window的变量,并通过指针将其提供给函数:

void LIB_CreateWindow( LIB_Window *ptr_wnd, ..... );

int main( void )
{
    .....

    LIB_Window wind;
    LIB_CreateWindow( &wnd, ..... );

    .....
}


当然,函数LIB_WindowLIB_DestroyWindow数据结构的内存释放仅在动态分配变量的内存时才有效:

LIB_DestroyWindow()
{
    .....

    free(window); // <--- this only works if window was allocated by malloc 
}