2017-07-18 10 views
1

Ich versuche, eine kleine kleine Spielengine in C mit Direct2D zu schreiben. Ich verwende nicht den Windows C-Compiler; aber stattdessen mit MinGW.Inkompatible Zeigertypen mit Direct2D

jedoch die C-Deklarationen jede Verwendung für ID2D1HwndRenderTarget bekomme ich diesen Fehler:

graphics.c:45:37: warning: passing argument 1 of 'graphics->_target->lpVtbl->Base.BeginDraw' from incompatible pointer type [ 
-Wincompatible-pointer-types] 
    ID2D1HwndRenderTarget_BeginDraw(graphics->_target); 
            ^
graphics.c:45:37: note: expected 'ID2D1RenderTarget * {aka struct ID2D1RenderTarget *}' but argument is of type 'ID2D1HwndRen 
derTarget * {aka struct ID2D1HwndRenderTarget *}' 

Ich habe ein graphics_t Typ wie folgt definiert:

und die Funktionen graphics_begin_draw:

void graphics_begin_draw(graphics_t *graphics) { 
    ID2D1HwndRenderTarget_BeginDraw(graphics->_target); 
} 

ID2D1HwndRenderTarget_BeginDraw ist ein Makro und f rom, was ich sammeln kann, scheint es richtig zu finden das Mitglied BeginDraw ist ein Teil von graphics->_target->lpVtbl->Base.BeginDraw; jedoch Base.BeginDraw dauert eine ID2D1RenderTarget * und keine ID2D1HwndRenderTarget *.

Von dem, was ich über die ID2D1HwndRenderTarget es verstehen erbt von ID2D1RenderTarget so kann ich sehen, warum die Base.BeginDraw ein ID2D1RenderTarget * erwarten würde; Gibt es eine Möglichkeit, diese Warnungen zu umgehen?

ich könnte stattdessen eine neue Definition des Makros erstellen, die die Besetzung der Fall ist, aber ich bin nicht sicher, ob dies die richtige Lösung ist:

#define _ID2D1HwndRenderTarget_BeginDraw(this) (this)->lpVtbl->BeginDraw((ID2D1RenderTarget *)this) 

Dies alles in der Header-Datei definiert ist, die sein kann gefunden here.

+0

Ich habe ein Mantra über Casting: "Jedes Mal, wenn Sie eine Besetzung verwenden, stirbt ein Kätzchen". Casting * normalerweise * bedeutet, dass Sie etwas falsch machen. Wenn Sie ein '' ID2D1HwndRenderTarget'' an ein '' ID2D1RenderTarget'' übergeben durften, würde der Compiler es Ihnen erlauben. Töte keine Kätzchen :-) – Neil

+0

@Neil Du hast recht; Ich meinte die Besetzung als Versuch, die Warnung naiv zu unterdrücken, ohne darüber nachzudenken, wie das Makro tatsächlich funktionierte. – jacob

+2

Die C-Sprache ist nicht gerade die produktivste Methode zum Schreiben von Direct2D-Code. Das Konzept der Schnittstellen und der Typvererbung fehlt vollständig, ist aber der Kern der Funktionsweise der API. Der Compiler hat keine Ahnung, dass die Strukturtypen miteinander verwandt sind, also die Warnung. Sie werden viel mehr von ihnen bekommen, in Betracht ziehen, die Warnung zu deaktivieren, um weiter zu kommen. Oder schreiben Sie den Code in die fiktive, aber praktische Untermenge "C with classes", die ein C++ - Compiler unterstützt, einige Chancen, dass Sie die intelligenten Zeigertypen finden, die den Schnittstellenzeiger umschließen können. –

Antwort

0

Ich schrieb ein Makro, das die Warnung deaktiviert, so dass ich etwas von der Unordnung aus dem Gebäude entfernen kann.

#define IGNORE_INCOMPATIBLE_POINTER_TYPES(block) \ 
_Pragma("GCC diagnostic push") \ 
_Pragma("GCC diagnostic ignored \"-Wincompatible-pointer-types\"") \ 
block \ 
_Pragma("GCC diagnostic pop") 
Verwandte Themen