2017-06-16 65 views
-1

我無法執行一些winapi代碼。我不知道是因爲我錯過了編譯過程中的某些東西,或者測試程序是否錯誤;但是當我執行該程序時,位圖定義行給出段錯誤嘗試執行MinGW編譯的C++ winapi測試程序的分段錯誤

這裏是測試程序

#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教程,並創建了一個窗口之前,所以我認爲我的MinGW安裝沒有任何錯誤。

可能是什麼問題?

+0

我不認爲'Gdiplus :: *的PixelFormat PF =新Gdiplus ::的PixelFormat();'是正確的。 'PixelFormat'只是一個整數,所以你最終調用'Gdiplus :: Bitmap'的時候是0.你應該傳入一個[defined pixels format constants](https://msdn.microsoft.com/ EN-US /庫/ ms534412(v = vs.85)的.aspx)。另外,你不必在C++中使用new。通常情況下,如果你根本沒有「新」,那會更好。 – user4581301

+1

GDI +也需要顯式初始化。我不知道如何在C++中做到這一點。 – andlabs

+0

Windows不會發出分段錯誤。什麼是您的運行時環境? – IInspectable

回答

1

錯誤是因爲GDI +未被初始化。您可以簡單地在mainGdiplus::GdiplusShutdown的頂部撥打Gdiplus::GdiplusStartup,但通過將其包裝到課程中,我們可以採取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.

+0

Nitpick:GDI +,而不是GDI;它們是兩個獨立的API,只是共享名稱。你也可能想解釋一下爲什麼你切換到'PixelFormat32bppARGB',因爲這仍然是你的答案和問題(而'PixelFormatUndefined'或'PixelFormatDontCare')之間的區別。 – andlabs

+0

將正確。我選擇了32位RGB,因爲我不認爲OP知道他們從指針中得到了什麼。而且我不喜歡驚喜,你可以從不關心的事情中得到什麼樣的驚喜。 – user4581301

+0

這就是爲什麼我說你應該在你的回答中說的原因= P – andlabs