2009-07-03 6 views
5

Difficile trovare un titolo appropriato per questo problema. Comunque ...Libreria di altri # conflitto di denominazione dei caratteri

Attualmente sto lavorando a un GUI per i miei giochi in SDL. Ho terminato il disegno del software e sono partito per iniziare la parte OpenGL di esso quando si è verificato un errore strano. Ho incluso l'intestazione "SDL/SDL_opengl.h" e compilato. Si genera "errore C2039: 'DrawTextW': non è un membro di 'GameLib :: FontHandler'", che è un errore abbastanza semplice, ma non ho nulla chiamato DrawTextW, solo FontHandler :: DrawText. Cerco DrawTextW e lo trovo in una chiamata #define nell'intestazione "WinUser.h"!

//WinUser.h 
#define DrawText DrawTextW 

Apparentemente sostituisce mia DrawText con DrawTextW! Come posso impedirmi di riversarsi nel mio codice in quel modo?

È una cosa secondaria cambiare il nome della mia funzione, ma i conflitti di denominazione come questo sembrano piuttosto pericolosi e mi piacerebbe davvero sapere come evitarli tutti insieme.

Cheers!

risposta

9

Hai un paio di opzioni, ognuno dei quali succhiare.

  • Aggiungi #undef DrawText nel proprio codice
  • Non includere windows.h. Se un'altra libreria lo include per te, non includerlo direttamente. Invece, includilo in un file .cpp separato, che può quindi esporre le proprie funzioni wrapper nella sua intestazione.
  • Rinomina il tuo DrawText.

Quando possibile, di solito scelgo l'opzione centrale. windows.h si comporta male in innumerevoli altri modi (ad esempio, in realtà non viene compilato se non si abilitano le estensioni C++ proprietarie di Microsoft), quindi lo evito semplicemente come la piaga. Non viene incluso nei miei file se posso aiutarlo. Invece, scrivo un file .cpp separato per contenerlo ed esporre la funzionalità di cui ho bisogno.

Inoltre, sentitevi liberi di inviarlo come bug e/o feedback su connect.microsoft.com. Windows.h è un'intestazione mal progettata male, e se le persone attirano l'attenzione di Microsoft su di esso, c'è una (sottile) possibilità che un giorno possano risolverlo.

La buona notizia è che windows.h è l'solo intestazione che si comporta male.Generalmente gli altri header tentano di prefissare i loro macro con un nome specifico della libreria per evitare conflitti di nome, cercano di evitare la creazione di macro per nomi comuni e cercano di evitare l'uso di più macro del necessario.

+0

Sì, Windows.h si scontrano. Suppongo sia giusto lamentarsi che non si compili senza le estensioni ms abilitate, ma è anche ragionevole che un'intestazione specifica di ms debba (richiedere quelle estensioni). – bobobobo

5

È uno sfortunato effetto collaterale di #include ing <windows.h>. Supponendo che non sta usando Windows' DrawText() qualsiasi punto del programma, è perfettamente sicuro per #undef subito dopo:

// wherever you #include <windows.h>, or any other windows header 
#include <windows.h> 
#undef DrawText 
+0

Grazie! Compila bene ora. Abbastanza un effetto collaterale fastidioso davvero. Sembra che SDL_opengl.h includa windows.h, ma #undef fa il suo lavoro. È possibile che windows.h sia stato scritto diversamente per evitare questo problema? – Zoomulator

+1

Potrebbe. Ma ciò richiederebbe a Microsoft di prendersene cura. – jalf

+1

@jalf Devi considerare le cose nel loro contesto. Quell'API ha più di 30 anni, cosa ti aspetti che Microsoft faccia? Rompere la compatibilità? Controlla il blog di Raymond Chen a volte e inizierai a capire perché la programmazione per Windows è così dolorosa a volte e perché molte cose non possono essere risolte. – minexew

4

Non c'è modo generale di evitare questo problema - una volta che si #include un file di intestazione utilizzando il preprocessore può ridefinire qualsiasi nome che gli piace, e non c'è nulla che tu possa fare al riguardo. Puoi #undef il nome, ma questo presuppone che tu sappia che il nome era #definito in primo luogo.

0

Solo #undef i simboli che non si desidera. Ma fare in modo di includere windows.h e farlo prima di includere SDL:

#include <windows.h> 
#undef DrawText 

#include <SDL/SDL_opengl.h>