本文介绍了引发OpenGL异常:读取访问冲突,窗口为0xCCCCCCCC的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用的是我上一个问题中描述的框架.

I am using the same framework which I had described in the previous question.

我通过创建一个新的dll解决了此问题,而不仅仅是将项目的构建类型从"Windows应用程序(.exe)"更改为"DLL(.dll)".

I solved it by creating a fresh dll instead of just changing the build type of the project from 'Windows Application (.exe)' to 'DLL (.dll)'.

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

But now when I use a variable of type GLFWwindow* in my structure and try to write or read. It always causes to pop up write access or read access violation respectively. The exception comes abruptly just as the window starts and then closes, showing the exception.

该异常表示以下内容:-

The exception says the following:-

引发异常:读取访问冲突.
窗口是0xCCCCCCCCCC.

Exception thrown: read access violation.
window was 0xCCCCCCCC.

它发生在GLFW的window.c文件中,它指向试图读取它的函数.我什至尝试使用指针来修改窗口,但仍然无法正常工作.

It happens in the window.c file of GLFW and it points to the function which tries to read it. I even tried to use pointers to modify the window but still it didn't work.

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

Here is the code for the framework:- Modified!

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();
}

推荐答案

函数LIB_CreateWindow返回指向局部变量LIB_Window wind;的指针.函数终止后,变量将超出范围,并且指针指向无处".这是未定义的行为.请注意,函数中的局部变量是在堆栈上分配的,当函数终止时,该变量立即被释放.

The function LIB_CreateWindow returns a pointer to the loacal variable LIB_Window wind;. Once the function terminates, the variable goes out of scope and pointer points to "nowhere". This is an undefined behavior. Note, a local variable in a function is allocated on the stack, which is immediately freed, when the function is terminated.

您可以通过声明变量static来快速解决此问题:

You can fix this quickly, by declare the variable static:

static LIB_Window wind;

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

But, if you do so, then of course the library can only manage one window.

要么创建动态分配的变量,要么

Either you create a dynamically allocated variable,

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

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

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

or you declare the variable of type LIB_Window outside the function and provide it to the function by pointer:

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

int main( void )
{
    .....

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

    .....
}


当然,在函数LIB_DestroyWindow中,LIB_Window数据结构的内存释放仅在变量的内存是动态分配的情况下才有效:


Of course, the memory release of the LIB_Window data structure, in the function LIB_DestroyWindow, only works if the memory for the variable was dynamically allocated:

LIB_DestroyWindow()
{
    .....

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

这篇关于引发OpenGL异常:读取访问冲突,窗口为0xCCCCCCCC的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-23 06:51
查看更多