简体   繁体   English

使用MinGW的C中的分段错误

[英]Segmentation fault in C using MinGW

The code compiles but crashes when run. 代码可以编译,但是在运行时崩溃。

I think it is VertexShaderSource and FragmentShaderSource that are causing problems but I can't seem to find it. 我认为是VertexShaderSource和FragmentShaderSource引起了问题,但我似乎找不到它。

I have been trying to solve this for days now, so your help would be much appreciated. 几天来我一直在努力解决这个问题,非常感谢您的帮助。

If the following lines of code are removed the program seems to run as intended. 如果删除以下代码行,则该程序似乎按预期运行。

GLuint RedShader = CreateShader();
glUseProgram(RedShader);

Here is the command line used to compile. 这是用于编译的命令行。

gcc -g ..\\Source\\main.c ..\\Source\\Window.c ..\\Source\\OpenGL.c ..\\Source\\Shader.c -lopengl32 -lgdi32 -o ..\\Binary\\Project.exe gcc -g .. \\ Source \\ main.c .. \\ Source \\ Window.c .. \\ Source \\ OpenGL.c .. \\ Source \\ Shader.c -lopengl32 -lgdi32 -o .. \\ Binary \\ Project.exe

Here is a snippet from the GDB console: 这是GDB控制台的代码段:

Program received signal SIGSEGV, Segmentation fault. 程序收到信号SIGSEGV,分段故障。

0x00000000 in ?? 0x00000000 in ?? () ()

(gdb) where (gdb)在哪里

0x00000000 in ?? 0x00000000 in ?? () ()

0x00401991 in CreateShader (VertexShaderSource=0x26f018, >FragmentShaderSource=0x26f014) at ..\\Source\\Shader.c:5 .. \\ Source \\ Shader.c:5中的CreateShader中的0x00401991(VertexShaderSource = 0x26f018,> FragmentShaderSource = 0x26f014)

0x00401432 in main () at ..\\Source\\Main.c:12 主()中的0x00401432位于.. \\ Source \\ Main.c:12

Here is the Code: 这是代码:

Main.c Main.c

#include "..\Header\Window.h"
#include "..\Header\Shader.h"


int main()
{
    Project_CreateWindow("Project", 512, 512);

    float Vertices[] = {-0.5f, -0.5f, 0.0f, 0.5f, -0.5f, 0.0f, 0.0f, 0.5f, 0.0f};

    GLuint VBO;
    glGenBuffers(1, &VBO);
    glBindBuffer(GL_ARRAY_BUFFER, VBO);
    glBufferData(GL_ARRAY_BUFFER, sizeof(Vertices), Vertices, GL_STATIC_DRAW);
    glEnableVertexAttribArray(0);
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);

    GLuint RedShader = CreateShader();
    glUseProgram(RedShader);

    glClearColor(0.0f, 0.0f, 0.0f, 0.0f);

    for(;;)
    {
        glClear(GL_COLOR_BUFFER_BIT);
        glDrawArrays(GL_TRIANGLES, 0, 3);
        Project_UpdateWindow();
    }

    glDisableVertexAttribArray(0);

    Project_DestroyWindow();

    return 0;
}

Window.h 窗口

#ifndef WINDOW_HEADER
#define WINDOW_HEADER

#include <windows.h>
#include <GL\GL.h>
#include "..\Header\OpenGL.h"

void Project_CreateWindow(const char * Title, const unsigned short Width, const unsigned short Height);
void Project_DestroyWindow();
void Project_UpdateWindow();

#endif

Window.c 窗口

#include "..\Header\Window.h"

static HDC DeviceContext;
static HWND Window;
static HGLRC RenderContext;

LRESULT CALLBACK EventHandler(HWND Window, UINT Message, WPARAM WordParameter, LPARAM LongParameter);

void Project_CreateWindow(const char * Title, const unsigned short Width, const unsigned short Height)
{
    WNDCLASSEX WindowClass = {sizeof(WNDCLASSEX), CS_OWNDC, EventHandler, 0, 0, GetModuleHandle(0), 0, 0, 0, 0, "WindowClass", 0};
    RegisterClassEx(&WindowClass);
    Window = CreateWindowEx(0, WindowClass.lpszClassName, Title, WS_OVERLAPPEDWINDOW, (GetSystemMetrics(SM_CXSCREEN) / 2) - (Width / 2), (GetSystemMetrics(SM_CYSCREEN) / 2) - (Height / 2), Width, Height, 0, 0, WindowClass.hInstance, 0);
    PIXELFORMATDESCRIPTOR PixelFormat = {sizeof(PIXELFORMATDESCRIPTOR), 1, PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER, PFD_TYPE_RGBA, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0};
    if ((DeviceContext = GetDC(Window)) == 0)
    {
        //TODO: Device Context Creation Failed
    }
    SetPixelFormat(DeviceContext, ChoosePixelFormat(DeviceContext, &PixelFormat), &PixelFormat);
    if ((RenderContext = wglCreateContext(DeviceContext)) == 0)
    {
        //TODO: Render Context Creation Failed
    }
    if ((wglMakeCurrent(DeviceContext, RenderContext)) == 0)
    {
        //TODO: Make Context Current Failed
    }
    ShowWindow(Window, SW_SHOW);
    GetOpenGLFunctionPointers();
}

void Project_DestroyWindow()
{
    wglMakeCurrent(0, 0);
    wglDeleteContext(RenderContext);
    ReleaseDC(Window, DeviceContext);
    DestroyWindow(Window);
}

void Project_UpdateWindow()
{
    MSG Message;
    if (PeekMessage(&Message, 0, 0, 0, PM_REMOVE))
    {
        TranslateMessage(&Message);
        DispatchMessage(&Message);
    }
    SwapBuffers(DeviceContext);
}

LRESULT CALLBACK EventHandler(HWND Window, UINT Message, WPARAM WordParameter, LPARAM LongParameter)
{
    return DefWindowProc(Window, Message, WordParameter, LongParameter);
}

OpenGL.h OpenGL.h

#ifndef OPENGL_HEADER
#define OPENGL_HEADER

#include <stddef.h.>
#include <GL\GL.h>
#include <windows.h>
#include <Wingdi.h>

#define GL_ARRAY_BUFFER                   0x8892
#define GL_STATIC_DRAW                    0x88E4
#define GL_VERTEX_SHADER                  0x8B31
#define GL_FRAGMENT_SHADER                0x8B30

typedef char GLchar;
typedef ptrdiff_t GLsizeiptr;

extern void (* glGenBuffers) (GLsizei n, GLuint *buffers);
extern void (* glBindBuffer) (GLenum target, GLuint buffer);
extern void (* glBufferData) (GLenum target, GLsizeiptr size, const void *data, GLenum usage);
extern void (* glEnableVertexAttribArray) (GLuint index);
extern void (* glVertexAttribPointer) (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void *pointer);
extern void (* glDisableVertexAttribArray) (GLuint index);
extern GLuint (* glCreateProgram) (void);
extern GLuint (* glCreateShader) (GLenum type);
extern void (* glShaderSource) (GLuint shader, GLsizei count, const GLchar *const*string, const GLint *length);
extern void (* glCompileShader) (GLuint shader);
extern void (* glAttachShader) (GLuint program, GLuint shader);
extern void (* glLinkProgram) (GLuint program);
extern void (* glUseProgram) (GLuint program);

void GetOpenGLFunctionPointers();

#endif

OpenGL.c OpenGL.c

#include "..\Header\OpenGL.h"

#include <stdio.h>

void *GetOpenGLFunctionAddress(const char *name);

void (* glGenBuffers) (GLsizei n, GLuint *buffers);
void (* glBindBuffer) (GLenum target, GLuint buffer);
void (* glBufferData) (GLenum target, GLsizeiptr size, const void *data, GLenum usage);
void (* glEnableVertexAttribArray) (GLuint index);
void (* glVertexAttribPointer) (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void *pointer);
void (* glDisableVertexAttribArray) (GLuint index);
GLuint (* glCreateProgram) (void);
GLuint (* glCreateShader) (GLenum type);
void (* glShaderSource) (GLuint shader, GLsizei count, const GLchar *const*string, const GLint *length);
void (* glCompileShader) (GLuint shader);
void (* glAttachShader) (GLuint program, GLuint shader);
void (* glLinkProgram) (GLuint program);
void (* glUseProgram) (GLuint program);

void GetOpenGLFunctionPointers()
{
    glGenBuffers = (void *)GetOpenGLFunctionAddress("glGenBuffers");
    glBindBuffer = (void *)GetOpenGLFunctionAddress("glBindBuffer");
    glBufferData = (void *)GetOpenGLFunctionAddress("glBufferData");
    glEnableVertexAttribArray = (void *)GetOpenGLFunctionAddress("glEnableVertexAttribArray");
    glVertexAttribPointer = (void *)GetOpenGLFunctionAddress("glVertexAttribPointer");
    glDisableVertexAttribArray = (void *)GetOpenGLFunctionAddress("glDisableVertexAttribArray");
    glCreateProgram = (void *)GetOpenGLFunctionAddress("glCreateProgram");
    glCreateShader = (void *)GetOpenGLFunctionAddress("glCreateShader");
    glShaderSource = (void *)GetOpenGLFunctionAddress("glShaderSource");
    glCompileShader = (void *)GetOpenGLFunctionAddress("glCompileShader");
    glAttachShader = (void *)GetOpenGLFunctionAddress("glAttachShader");
    glLinkProgram = (void *)GetOpenGLFunctionAddress("glLinkProgram");
    glUseProgram = (void *)GetOpenGLFunctionAddress("glUseProgram");
}

void *GetOpenGLFunctionAddress(const char *FunctionName)
{
  void *FunctionPointer = (void *)wglGetProcAddress(FunctionName);

  if(FunctionPointer == 0 || (FunctionPointer == (void*)0x1) || (FunctionPointer == (void*)0x2) || (FunctionPointer == (void*)0x3) || (FunctionPointer == (void*)-1))
  {
        HMODULE Module = LoadLibraryA("opengl32.dll");
        FunctionPointer = (void *)GetProcAddress(Module, FunctionName);

        if(FunctionPointer == 0 || (FunctionPointer == (void*)0x1) || (FunctionPointer == (void*)0x2) || (FunctionPointer == (void*)0x3) || (FunctionPointer == (void*)-1))
        {
            printf("%s %i", "Invalid OpenGL Function Pointer, Last Error:", GetLastError());
        }
  }

  return FunctionPointer;
}

Shader.h 着色器

#ifndef SHADER_HEADER
#define SHADER_HEADER

#include "..\Header\OpenGL.h"

GLuint CreateShader();

#endif

Shader.c 着色器

    #include "..\Header\Shader.h"

GLuint CreateShader()
{
    const GLchar * VertexShaderSource  = "#version 330 core\n layout(location = 0) in vec3 vertexPosition_modelspace;\n void main(){\n gl_Position.xyz = vertexPosition_modelspace;\n gl_Position.w = 1.0;\n }";
    const GLchar * FragmentShaderSource = "#version 330 core\n out vec3 color;\n void main(){\n color = vec3(1.0f, 0.55f, 0.0f);\n }";

    GLuint ShaderProgram = glCreateProgram();

    GLuint VertexShader = glCreateShader(GL_VERTEX_SHADER);
    GLuint FragmentShader = glCreateShader(GL_FRAGMENT_SHADER);

    glShaderSource(VertexShader, 1, &VertexShaderSource, 0);
    glShaderSource(FragmentShader, 1, &FragmentShaderSource, 0);

    glCompileShader(VertexShader);
    glCompileShader(FragmentShader);

    glAttachShader(ShaderProgram, VertexShader);
    glAttachShader(ShaderProgram, FragmentShader);

    glLinkProgram(ShaderProgram);

    return ShaderProgram;
}

Forgot the calling convention eg 忘记通话惯例,例如

extern void (* glGenBuffers) (GLsizei n, GLuint *buffers);

Should be changed to: 应更改为:

extern void (__stdcall * glGenBuffers) (GLsizei n, GLuint *buffers);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM