2017-06-16 1 views
-1

Ich habe Probleme, einige Winapi-Code auszuführen. Ich weiß nicht, ob der Grund dafür ist, dass ich etwas beim Kompilieren verpasst habe oder das Testprogramm falsch ist. aber wenn ich das Programm ausführe, gibt die Bitmap-Definitionszeile einen segfault.Segmentierungsfehler, der versucht, ein MinGW kompiliertes C++ Winapi-Testprogramm auszuführen

hier ist das Prüfprogramm

#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; 
} 

und hier ist die Kompilation Anweisung:

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

Wenn ich ausführen, ich diesen Wurf haben:

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) {} 

ich einige tat Winapi Tutorial und erstellt ein Fenster vor, so denke ich, dass meine MinGW Installation nichts falsch ist.

Was könnte das Problem sein?

+0

Ich glaube nicht, 'Gdiplus :: Pixelformat * pf = new Gdiplus :: Pixelformat();' richtig ist. 'PixelFormat' ist nur ein int, also was du sagst, heißt' Gdiplus :: Bitmap' mit 0. Du sollst eine der [definierten Pixelformat-Konstanten] übergeben (https://msdn.microsoft.com/ de-de/library/ms534412 (v = V.85) .aspx). Außerdem müssen Sie in C++ nicht alles "neu" machen. Normalerweise ist es besser, wenn du gar nicht "neu" bist. – user4581301

+1

GDI + benötigt auch explizite Initialisierung. Ich weiß nicht, wie man das in C++ macht. – andlabs

+0

Windows gibt keine Segmentierungsfehler aus. Was ist Ihre Laufzeitumgebung? – IInspectable

Antwort

1

Der Fehler liegt daran, dass GDI + nicht initialisiert wird. Sie könnten einfach Gdiplus::GdiplusStartup am Anfang von main und Gdiplus::GdiplusShutdown am Ende aufrufen, aber indem wir es in eine Klasse wickeln, nehmen wir advantage of RAII und automatisieren die Initialisierung und Freigabe mit weniger Aufwand und Aufhebens, sollte etwas schief gehen.

#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 +, nicht GDI; Sie sind zwei separate APIs, die nur Namen teilen. Vielleicht möchten Sie auch erklären (oder kopieren Sie die Erklärung in Ihrem Kommentar), warum Sie auf 'PixelFormat32bppARGB' gewechselt haben, da das immer noch ein Unterschied zwischen Ihrer Antwort und der Frage ist (und 0 ist entweder 'PixelFormatUndefined' oder' PixelFormatDontCare'). .. – andlabs

+0

Wird korrigiert. Ich habe 32bit RGB gewählt, weil ich nicht glaube, dass OP wusste, was sie vom Zeiger bekommen. Und ich mag keine Überraschungen, die Art von Überraschungen, die man bekommen kann, egal. – user4581301

+0

Das ist der Grund, warum ich sage, dass Sie das auch in Ihrer Antwort sagen sollten = P – andlabs