gpt4 book ai didi

c++ - 在另一个文件中添加全局变量时的奇怪行为

转载 作者:行者123 更新时间:2023-11-30 02:20:09 25 4
gpt4 key购买 nike

这是我的简单程序:

#include "stdafx.h"
#include<Windows.h>

LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
void initBackBuffer(HWND hwnd);

HDC hBackDC = NULL;
HBITMAP hBackBitmap = NULL;

const int WIDTH = 512;
const int HEIGHT = 512;

DWORD screenBuffer[WIDTH * HEIGHT];


void draw(HWND hwnd) {
HDC hWinDC = GetDC(hwnd);

SetBitmapBits(hBackBitmap, HEIGHT * WIDTH * sizeof(DWORD), (const void*)(screenBuffer));
BitBlt(hWinDC, 0, 0, WIDTH, HEIGHT, hBackDC, 0, 0, SRCCOPY);
ReleaseDC(hwnd, hWinDC);
}

int WINAPI wWinMain(HINSTANCE hInstace, HINSTANCE hPrevInstace, LPWSTR lpCmdLine, int nCmdShow) {
memset(screenBuffer, 0, sizeof(screenBuffer));
MSG msg = { 0 };
WNDCLASS wnd = { 0 };

wnd.lpfnWndProc = WndProc;
wnd.hInstance = hInstace;
wnd.lpszClassName = L"Window";

if (!RegisterClass(&wnd)) {
return 0;
}

HWND hwnd = CreateWindowEx(NULL, wnd.lpszClassName, L"Window",
WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, WIDTH, HEIGHT, NULL, NULL, hInstace, NULL);

if (!hwnd) {
return 0;
}

ShowWindow(hwnd, nCmdShow);
UpdateWindow(hwnd);

for (int i = 0; i <= 512; i++) {
screenBuffer[i * WIDTH + 0] = 0x00FF0000;
}

while (true) {
if(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
if (msg.message == WM_QUIT) {
break;
}

TranslateMessage(&msg);
DispatchMessage(&msg);
}


draw(hwnd);
}

return msg.wParam;
}

LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam){

switch (msg){
case WM_CREATE:
initBackBuffer(hwnd);
break;
case WM_DESTROY:
DeleteDC(hBackDC);
DeleteObject(hBackBitmap);
PostQuitMessage(0);
break;
}
return DefWindowProc(hwnd, msg, wParam, lParam);
}

void initBackBuffer(HWND hwnd) {
HDC hWinDC = GetDC(hwnd);

hBackDC = CreateCompatibleDC(hWinDC);
hBackBitmap = CreateCompatibleBitmap(hWinDC, WIDTH, HEIGHT);
SetBitmapBits(hBackBitmap, HEIGHT * WIDTH * sizeof(DWORD), (const void*)(screenBuffer));

SelectObject(hBackDC, hBackBitmap);
ReleaseDC(hwnd, hWinDC);
}

output符合预期。

我搬家了

const int WIDTH = 512;
const int HEIGHT = 512;

DWORD screenBuffer[WIDTH * HEIGHT];

进入 Global.h 并在我的主文件中添加了 #include "Global.h"

主文件:

#include "stdafx.h"
#include<Windows.h>
#include "Global.h"

LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
void initBackBuffer(HWND hwnd);

HDC hBackDC = NULL;
HBITMAP hBackBitmap = NULL;


void draw(HWND hwnd) {
HDC hWinDC = GetDC(hwnd);

SetBitmapBits(hBackBitmap, HEIGHT * WIDTH * sizeof(DWORD), (const void*)(screenBuffer));
BitBlt(hWinDC, 0, 0, WIDTH, HEIGHT, hBackDC, 0, 0, SRCCOPY);
ReleaseDC(hwnd, hWinDC);
}

int WINAPI wWinMain(HINSTANCE hInstace, HINSTANCE hPrevInstace, LPWSTR lpCmdLine, int nCmdShow) {
memset(screenBuffer, 0, sizeof(screenBuffer));
MSG msg = { 0 };
WNDCLASS wnd = { 0 };

wnd.lpfnWndProc = WndProc;
wnd.hInstance = hInstace;
wnd.lpszClassName = L"Window";

if (!RegisterClass(&wnd)) {
return 0;
}

HWND hwnd = CreateWindowEx(NULL, wnd.lpszClassName, L"Window",
WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, WIDTH, HEIGHT, NULL, NULL, hInstace, NULL);

if (!hwnd) {
return 0;
}

ShowWindow(hwnd, nCmdShow);
UpdateWindow(hwnd);

for (int i = 0; i <= 512; i++) {
screenBuffer[i * WIDTH + 0] = 0x00FF0000;
}

while (true) {
if(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
if (msg.message == WM_QUIT) {
break;
}

TranslateMessage(&msg);
DispatchMessage(&msg);
}


draw(hwnd);
}

return msg.wParam;
}

LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam){

switch (msg){
case WM_CREATE:
initBackBuffer(hwnd);
break;
case WM_DESTROY:
DeleteDC(hBackDC);
DeleteObject(hBackBitmap);
PostQuitMessage(0);
break;
}
return DefWindowProc(hwnd, msg, wParam, lParam);
}

void initBackBuffer(HWND hwnd) {
HDC hWinDC = GetDC(hwnd);

hBackDC = CreateCompatibleDC(hWinDC);
hBackBitmap = CreateCompatibleBitmap(hWinDC, WIDTH, HEIGHT);
SetBitmapBits(hBackBitmap, HEIGHT * WIDTH * sizeof(DWORD), (const void*)(screenBuffer));

SelectObject(hBackDC, hBackBitmap);
ReleaseDC(hwnd, hWinDC);
}

Global.h

#pragma once


const int WIDTH = 512;
const int HEIGHT = 512;

DWORD screenBuffer[WIDTH * HEIGHT];

我得到一个错误的 white window .

我不明白为什么会这样,因为编译器无论如何都会将 Global.h 的内容复制到主文件中,因此两种变体应该产生相同的结果。

这个问题的原因是什么?

最佳答案

这里有个错误:

const int WIDTH = 512;
const int HEIGHT = 512;
DWORD screenBuffer[WIDTH * HEIGHT];
void foo()
{
for (int i = 0; i <= 512; i++) {
screenBuffer[i * WIDTH + 0] = 0x00FF0000;
}
}

这应该是i < 512 .否则它会覆盖一个随机的内存位置,这可能会导致在不同的位置出现错误,或者如果幸运的话不会出现错误。调试器可能会报告一个无意义的错误,或者根本没有错误。如果screenBuffer是在堆栈上创建的,调试器可能会给出“堆损坏”错误。

考虑使用 std::vector以避免将来出现此问题。

vector<int> vec;
vec[vec.size()] = 0;//<- debug error

旁注:SetDIBitsToDeviceStretchDIBits将直接设置位:

void draw(HWND hwnd) 
{
BITMAPINFO bi;
bi.bmiHeader.biSize = sizeof(bi.bmiHeader);
bi.bmiHeader.biBitCount = 32;
bi.bmiHeader.biWidth = WIDTH;
bi.bmiHeader.biHeight = HEIGHT;
bi.bmiHeader.biPlanes = 1;
bi.bmiHeader.biCompression = BI_RGB;
HDC hdc = GetDC(hwnd);
SetDIBitsToDevice(hdc, 0, 0, WIDTH, HEIGHT, 0, 0, 0, HEIGHT, screenBuffer,
&bi, DIB_RGB_COLORS);
ReleaseDC(hwnd, hdc);
}

关于c++ - 在另一个文件中添加全局变量时的奇怪行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50073570/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com