基于WinAPI创建OpenGL渲染上下文并检查GL_VERSION遇编译链接错误求助
问题解决:WinAPI OpenGL代码编译链接错误修复
问题1:警告C28252、C28253(WinMain SAL注解不一致)
- 原因:自定义的WinMain参数SAL注解与Visual Studio标准库中WinMain的声明不匹配,尤其是第三个参数
LPSTR lpCmdLine在Unicode环境下标准类型应为LPWSTR,同时手动添加的SAL注解不符合编译器内置定义。 - 修复方法:使用Visual Studio兼容的标准WinMain声明,移除自定义SAL注解,改用系统默认的调用约定和参数类型:
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nShowCmd)WINAPI宏会自动处理调用约定,标准声明的参数类型与编译器内置定义完全一致,可直接消除注解不匹配警告。
问题2&3:错误LNK2019、LNK1120(未解析的外部符号main)
- 原因:项目默认设置为Console子系统,该模式会寻找
main函数作为程序入口;而当前代码使用WinMain作为Windows应用入口,需要切换到Windows子系统。另外代码中混用宽字符(如L"字符串"、CreateWindowW),若项目字符集为多字节也可能引发兼容问题。 - 修复方法:
- 右键项目→属性,打开项目配置面板
- 进入链接器→系统,将子系统设置为
Windows (/SUBSYSTEM:WINDOWS) - 进入常规,将字符集设置为
使用 Unicode 字符集
修改后的完整代码
#include <windows.h> #include <GL/GL.h> #pragma comment (lib, "opengl32.lib") LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam); int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nShowCmd) { MSG msg = { 0 }; WNDCLASS wc = { 0 }; wc.lpfnWndProc = WndProc; wc.hInstance = hInstance; wc.hbrBackground = (HBRUSH)(COLOR_BACKGROUND); wc.lpszClassName = L"oglversionchecksample"; wc.style = CS_OWNDC; if (!RegisterClass(&wc)) return 1; CreateWindowW(wc.lpszClassName, L"openglversioncheck", WS_OVERLAPPEDWINDOW | WS_VISIBLE, 0, 0, 640, 480, 0, 0, hInstance, 0); while (GetMessage(&msg, NULL, 0, 0) > 0) DispatchMessage(&msg); return 0; } LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { switch (message) { case WM_CREATE: { PIXELFORMATDESCRIPTOR pfd = { sizeof(PIXELFORMATDESCRIPTOR), 1, PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER, //Flags PFD_TYPE_RGBA, // The kind of framebuffer. RGBA or palette. 32, // Colordepth of the framebuffer. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24, // Number of bits for the depthbuffer 8, // Number of bits for the stencilbuffer 0, // Number of Aux buffers in the framebuffer. PFD_MAIN_PLANE, 0, 0, 0, 0 }; HDC ourWindowHandleToDeviceContext = GetDC(hWnd); int letWindowsChooseThisPixelFormat; letWindowsChooseThisPixelFormat = ChoosePixelFormat(ourWindowHandleToDeviceContext, &pfd); SetPixelFormat(ourWindowHandleToDeviceContext, letWindowsChooseThisPixelFormat, &pfd); HGLRC ourOpenGLRenderingContext = wglCreateContext(ourWindowHandleToDeviceContext); wglMakeCurrent(ourWindowHandleToDeviceContext, ourOpenGLRenderingContext); MessageBoxA(0, reinterpret_cast<char*>(glGetString(GL_VERSION)), "OPENGL VERSION", 0); //wglMakeCurrent(ourWindowHandleToDeviceContext, NULL); Unnecessary; wglDeleteContext will make the context not current wglDeleteContext(ourOpenGLRenderingContext); PostQuitMessage(0); } break; default: return DefWindowProc(hWnd, message, wParam, lParam); } return 0; }
注:额外将(char*)glGetString(GL_VERSION)改为reinterpret_cast<char*>(glGetString(GL_VERSION)),替代C风格强制转换,更符合C++规范并避免潜在类型转换警告。
内容的提问来源于stack exchange,提问作者Mark Soir
相关产品推荐
相关产品推荐

