C++ ARB_调试_输出的访问冲突
我正在使用C++ ARB_调试_输出的访问冲突,c++,visual-c++,opengl,glload,C++,Visual C++,Opengl,Glload,我正在使用ARB\u DEBUG\u OUTPUT扩展来捕获OpenGL错误,但是程序在调用我的错误记录函数后崩溃 我使用中的代码设置扩展。下面是我用来设置回调的确切代码: glDebugMessageCallback((GLDEBUGPROC)debugCallbackARB, stderr); glEnable(GL_DEBUG_OUTPUT); glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS_ARB); glEnable(GL_DEPTH); 下面是debug
ARB\u DEBUG\u OUTPUT
扩展来捕获OpenGL错误,但是程序在调用我的错误记录函数后崩溃
我使用中的代码设置扩展。下面是我用来设置回调的确切代码:
glDebugMessageCallback((GLDEBUGPROC)debugCallbackARB, stderr);
glEnable(GL_DEBUG_OUTPUT);
glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS_ARB);
glEnable(GL_DEPTH);
下面是debugCallbackARB
void debugCallbackARB(GLenum source, GLenum type, GLuint id, GLenum severity,
GLsizei length, const GLchar *message, GLvoid *userParam)
{
(void)length;
FILE *outFile = (FILE*)userParam;
char finalMessage[256];
formatDebugOutputARB(finalMessage, 256, source, type, id, severity, message);
logger->debug("%s", finalMessage);
}
我使用带有无效参数的glEnable
来触发回调:
glDebugMessageCallback((GLDEBUGPROC)debugCallbackARB, stderr);
glEnable(GL_DEBUG_OUTPUT);
glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS_ARB);
glEnable(GL_DEPTH);
成功打印错误消息后,程序触发未处理的异常访问冲突执行位置0x00000500。
我正在使用SDL2创建OpenGL3.3核心概要文件调试上下文,并获取GL扩展指针
如果禁用扩展,程序不会在无效的glEnable
调用上崩溃
我怎样才能解决这个问题
计算机规格:
- NVIDIA GeForce GT 630
- ForceWare 327.23
- Windows 7 x64
编辑:我也尝试手动调用调试回调,但它不会触发异常。OpenGL回调函数使用
\uuu stdcall
调用约定,而不是MSVC2012中默认启用的\uuu cdecl
我将回调定义更改为
void CALLBACK debugCallbackARB(GLenum source, GLenum type, GLuint id, GLenum severity,
GLsizei length, const GLchar *message, GLvoid *userParam)
使用Windows API头定义的回调
宏
无效地址
0x00000500
的十进制数为1280,它恰好是传递给调用层次结构中更高一级的初始化函数的屏幕宽度参数。由于调用约定无效,此值是从堆栈中读取的,而不是调用函数的图形驱动程序设置的实际返回地址。调用回调函数并不奇怪,毕竟是您定义了函数。但是,您不应该添加ARB
后缀。此外,调用DebugMessageCallback
时,不需要对调用GLDEBUGPROC
的回调进行C-cast ptr-函数的签名适合,因此函数ptr已经具有正确的类型。关于崩溃,请检查调用堆栈-访问冲突是否发生在某些NVIDIA模块中?我想是的,但请确认。这句话的意思是什么:(void)length代码>?因为它不起任何作用,我得到的印象是你实际上打算在那里做其他事情?@AndonM.Coleman:这就是阻止编译器抱怨未使用变量的C/C++方法D通常您会看到它被包装在宏中,类似于#define UNUSED(x)(void)x代码>啊,这是一个很好的观点。我没有注意到格式化字符串的长度与输入调试消息的长度无关。当消息长度大于255时,它(希望)会截断消息。感谢您指出函数签名。事实证明,它确实有一个错误的调用约定(cdecl而不是stdcall)。