Domanda

ho un po 'di codice C ++ che include un metodo chiamato CreateDirectory(). In precedenza il codice unico STL e Boost utilizzato, ma di recente ho dovuto includere <windows.h> così ho potuto CSIDL_LOCAL_APPDATA look-up.

Ora, questo codice:

filesystem.CreateDirectory(p->Pathname()); // Actually create it...

Non è più compila:

error C2039: 'CreateDirectoryA' : is not a member of ...

che corrisponde a questa macro in winbase.h:

#ifdef UNICODE
#define CreateDirectory  CreateDirectoryW
#else
#define CreateDirectory  CreateDirectoryA
#endif // !UNICODE

La pre-processore sta ridefinendo il mio metodo di chiamata. C'è un modo possibile per evitare questa collisione di denominazione? O devo rinominare il mio metodo CreateDirectory()?

È stato utile?

Soluzione

Si sarà meglio se si rinomina il metodo CreateDirectory. Se è necessario utilizzare le API di Windows, combattendo con Windows.h è una battaglia persa.

Per inciso, se si dovesse coerente in compreso windows.h, questa sarà ancora la compilazione. (Anche se si potrebbe avere problemi in altri luoghi).

Altri suggerimenti

È possibile creare un modulo il cui unico scopo è quello #include <windows.h> e cercare CSIDL_LOCAL_APPDATA avvolto in una funzione.

int get_CSIDL_LOCAL_APPDATA(void)
{
    return CSIDL_LOCAL_APPDATA;
}

btw, ben fatto per lavorare fuori quello che è successo!

#undef CreateDirectory

Come sviluppatore che lavora su una croce codebase piattaforma, questo è un problema. L'unico modo per affrontare il problema è quello di

  • garantire che windows.h è - su Windows costruisce almeno - universalmente compreso. Poi la macro CreateDirectory è definito in ogni uno dei vostri unità di compilazione ed è universalmente sostituito con CreateDirectoryW. intestazioni precompilate sono ideali per questo

O, se questa è una proposta sgradevole, (ed è per me)

  • isolare windows.h utilizzo in Windows file di utilità specifici. Creare file che esportano la funzionalità richiesta di base. I file di intestazione devono utilizzare i tipi di dati che sono compatibili con, ma non dipendono l'inserimento di windows.h. Il file di implementazione cpp deve (ovviamente) utilizzare windows.h.

Se le funzioni utlility devono includere i file di intestazione di progetto con i simboli contrastanti quindi il seguente modello è una necessità:

#include <windows.h>
#ifdef CreateDirectory
#undef CreateDirectory
#endif
// etc
#include "some_class_with_CreateDirectory_method.h"
// ...

Sarà necessario quindi chiamare in modo esplicito la versione non macro di tutte le funzioni API di Windows si ha # undef'd -. CreateDirectoryA o W etc

push macro, undef e pop di nuovo la macro:

#pragma push_macro("CreateDirectory")
#undef CreateDirectory
void MyClass::CreateDirectory()
{
 // ...
}
#pragma pop_macro("CreateDirectory")

Si noti che il nome conflitto di solito proviene da un certo file di intestazione viene incluso. Fino ad allora roba come CreateDirectory e GetMessage non viene tirato in visibilità e il codice compila senza un problema.

È possibile isolare tale inclusione in un file di intestazione involucro e "#undef qualunque" al suo termine. Quindi, qualunque sia il nome che hai collisione sarà andato. A meno che, naturalmente, è necessario utilizzare le macro nel proprio codice (sì, in modo molto probabile ...)

Si può prendere un back up di CreateDirectory, allora non definirlo, e quindi definire di nuovo quando hai finito il tuo lavoro con te personalizzato.

#ifdef CreateDirectory
#define CreateDirectory_Backup CreateDirectory
#undef CreateDirectory
#endif

// ...
// Define and use your own CreateDirectory() here.
// ...

#ifdef CreateDirectory_Backup
#define CreateDirectory CreateDirectory_Backup
#undef CreateDirectory_Backup
#endif
#pragma push_macro("CreateDirectory")

Se non funziona, invece di rinominare è possibile utilizzare il proprio spazio dei nomi per le funzioni.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top