尝试执行 MinGW 编译的 C++ winapi 测试程序的分段错误

Segmentation fault trying to execute a MinGW compiled C++ winapi test program

我在执行某些 winapi 代码时遇到问题。不知道是编译过程中遗漏了什么还是测试程序出错了;但是当我执行程序时,位图定义行给出了 segfault.

这里是测试程序

#include <windows.h>
#include <gdiplus.h>

int WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
  Gdiplus::PixelFormat* pf = new Gdiplus::PixelFormat();
  Gdiplus::Bitmap* bitmap = new Gdiplus::Bitmap(100, 100, *pf);
  return 0;
}

这里是编译说明:

> mingw32-g++ main.cpp -lgdiplus -o main.exe

当我执行时,我有这个抛出:

Program received signal SIGSEGV, Segmentation fault.
0x00403da3 in Gdiplus::Image::Image (this=0x0, image=0x0, status=Gdiplus::Ok) at c:/mingw/include/gdiplus/gdiplusheaders.h:142
142                     nativeImage(image), lastStatus(status) {}

我之前做了一些winapi教程并创建了一个window所以我认为我的MinGW安装没有问题。

可能是什么问题?

错误是因为 GDI+ 没有被初始化。您可以简单地在 main 的顶部调用 Gdiplus::GdiplusStartup 并在末尾调用 Gdiplus::GdiplusShutdown,但是通过将其包装在 class 中,我们可以采用 advantage of RAII 并自动执行如果出现任何问题,初始化和发布都不会那么混乱和大惊小怪。

#include <stdexcept>
#include <windows.h>
#include <gdiplus.h>
#include <stdio.h>

// GDI+ wrapper class
class GdiplusRAII
{
    ULONG_PTR gdiplusToken;

public:

    GdiplusRAII()
    {
        Gdiplus::GdiplusStartupInput input;
        Gdiplus::Status status = Gdiplus::GdiplusStartup(&gdiplusToken, &input, NULL);
        if (status != Gdiplus::Ok)
        {
            throw std::runtime_error("Could not initialize GDI+");
        }
    }
    ~GdiplusRAII()
    {
        Gdiplus::GdiplusShutdown(gdiplusToken);
    }

};

int WinMain(HINSTANCE ,
            HINSTANCE ,
            LPSTR ,
            int ) // not using the parameters so I left them out.
{
    GdiplusRAII raii; // initialize GDI+

    // no need to new a PixelFormat. It is just an int associated with a 
    // collection of defined constants. I'm going to pick one that sounds 
    // reasonable to minimize the potential for a nasty surprise and use it 
    // directly in the Gdiplus::Bitmap constructor call. 

    // Probably no need to new the bitmap. In fact you'll find that most of 
    // the time it is better to not new at all. 
    Gdiplus::Bitmap bitmap(100, 100, PixelFormat32bppARGB);
    return 0;
    // GDI+ will be shutdown when raii goes out of scope and its destructor runs.
}

Documentation on PixelFormat.