我在使用指针设置类属性时出现问题,这是我的代码:(此版本将编译,但您需要打开扫雷窗口。)
WindowObject.h:
#ifndef WINDOWOBJECT_H_INCLUDED
#define WINDOWOBJECT_H_INCLUDED
#include <windows.h>
#include <stdio.h>
class WindowObject
{
public:
WindowObject();
BYTE* getPixelMap() const;
void setPixelMap(BYTE* bitPointer);
void getPixelMap(HWND hwnd);
private:
BYTE* mPixelMap;
};
#endif
WindowObject.cpp:
#include "WindowObject.h"
WindowObject::WindowObject()
{
}
BYTE* WindowObject::getPixelMap() const
{
printf("getPixelMap: %d\n", mPixelMap[0]); // it crashes, bad pointer!!
return mPixelMap;
}
void WindowObject::setPixelMap(BYTE *bitPointer)
{
printf("setPixelMap 1: %d\n", bitPointer[0]); // It works!
mPixelMap = bitPointer;
printf("setPixelMap 2: %d\n", mPixelMap [0]); // Why does this works and getPixelMap doesn't???
}
void WindowObject::getPixelMap(HWND hwnd)
{
HDC hdcWindow, hdcMemDC = NULL;
HBITMAP hbmScreen = NULL;
BITMAP bmpScreen;
// Retrieve the handle to a display device context for the client
// area of the window.
hdcWindow = GetDC(hwnd);
// Create a compatible DC which is used in a BitBlt from the window DC
hdcMemDC = CreateCompatibleDC(hdcWindow);
if(!hdcMemDC)
{
MessageBoxA(hwnd, "CreateCompatibleDC has failed", "Failed", MB_OK);
goto done;
}
// Get the client area for size calculation
RECT rcClient;
GetClientRect(hwnd, &rcClient);
// Create a compatible bitmap from the Window DC
hbmScreen = CreateCompatibleBitmap(hdcWindow, rcClient.right-rcClient.left, rcClient.bottom-rcClient.top);
if(!hbmScreen)
{
MessageBoxA(hwnd, "CreateCompatibleBitmap Failed", "Failed", MB_OK);
goto done;
}
//Get the BITMAP from the HBITMAP
GetObject(hbmScreen,sizeof(BITMAP),&bmpScreen);
BITMAPFILEHEADER bmfHeader;
BITMAPINFOHEADER bi;
BYTE* bitPointer;
bi.biSize = sizeof(BITMAPINFOHEADER);
bi.biWidth = bmpScreen.bmWidth;
bi.biHeight = bmpScreen.bmHeight;
bi.biPlanes = 1;
bi.biBitCount = 32;
bi.biCompression = BI_RGB;
bi.biSizeImage = 0;
bi.biXPelsPerMeter = 0;
bi.biYPelsPerMeter = 0;
bi.biClrUsed = 0;
bi.biClrImportant = 0;
// Create a device independent bitmap that so that we can write to it directly
hbmScreen = CreateDIBSection(hdcMemDC, (BITMAPINFO *)&bi, DIB_RGB_COLORS, (void**)(&bitPointer), NULL, NULL);
// Select the compatible bitmap into the compatible memory DC.
SelectObject(hdcMemDC, hbmScreen);
// Bit block transfer into our compatible memory DC.
if ( !BitBlt(hdcMemDC, 0, 0, rcClient.right-rcClient.left, rcClient.bottom-rcClient.top, hdcWindow, 0, 0, SRCCOPY) )
{
MessageBox(hwnd, "BitBlt has failed", "Failed", MB_OK);
goto done;
}
// Create PixelMap
int width = (rcClient.right-rcClient.left),
height = (rcClient.bottom-rcClient.top);
printf("Inside getPixelMap: %d\n", bitPointer[0]); // it works!
setPixelMap(bitPointer);
done:
DeleteObject(hbmScreen);
DeleteObject(hdcMemDC);
ReleaseDC(hwnd, hdcWindow);
}
main.cpp中:
#include "WindowObject.h"
int main()
{
WindowObject wObj;
HWND hwnd;
hwnd = FindWindow(NULL, "Minesweeper");
if (hwnd)
{
wObj.getPixelMap(hwnd);
BYTE* bPointer = wObj.getPixelMap();
printf("After getPixelMap: %d", bPointer[0]);
}
}
程序崩溃了,它给了我一个“访问冲突读取位置”。我几乎100%确定问题来自我的指针,但我发现它在我的测试的每个阶段都有效,除非我用我的getPixelMap方法得到它。任何帮助将不胜感激!
答案 0 :(得分:1)
问题是这个数据成员要么没有初始化(如果类的对象是默认初始化的),要么是值0.因此使用成员函数getPixelMap()是不安全的。另外,我认为函数setPixelMap的参数的生命可能小于类的对象的生命。所以程序的行为是不确定的。
我认为最好使用智能指针或分配内存供数据成员自己使用。
答案 1 :(得分:0)
在函数getPixelMap(HWND hwnd)中,在保存指针之后但在返回之前,您在返回的位图上调用DeleteObject。因此,当您稍后访问位图时,它不再是有效指针,因为根据CreateDIBSection文档,它表示在调用DeleteObject时将取消分配位图。
您需要保留位图对象(hbmScreen)并稍后将其删除,可能在析构函数中。