Domanda

Sto lavorando con una libreria che ridefinisce NULL. Causa alcuni problemi con altre parti del mio programma. Non sono sicuro di cosa posso fare al riguardo. Qualche idea? Il mio programma è in C ++, la libreria è in C .

#ifdef NULL
#undef NULL
#endif

/**
 * NULL define.
 */
#define NULL    ((void *) 0)

Oh, e produce questi errori:

Generic.h:67: error: default argument for parameter of type 'LCD::LCDBase*' has type 'void*'
Generic.cpp: In constructor 'LCD::Generic::Generic(std::string, Json::Value*, int, LCD::LCDBase*)':
Generic.cpp:44: error: invalid conversion from 'void*' to 'QObject*'
Generic.cpp:44: error:   initializing argument 2 of 'LCD::LCDWrapper::LCDWrapper(LCD::LCDInterface*, QObject*)'
Generic.cpp: In member function 'void LCD::Generic::BuildLayouts()':
Generic.cpp:202: error: invalid conversion from 'void*' to 'LCD::Widget*'
Generic.cpp: In member function 'void LCD::Generic::AddWidget(std::string, unsigned int, unsigned int, std::string)':
Generic.cpp:459: error: invalid conversion from 'void*' to 'LCD::Widget*'
scons: *** [Generic.o] Error 1

Ecco il primo:

Generic(std::string name, Json::Value *config, int type, LCDBase *lcd = NULL);

Modifica: Ok, il cast funziona esplicitamente, ma come faccio a lanciare un puntatore a funzione?

È stato utile?

Soluzione

Puoi ricostruire la libreria senza che sia definito? Questo è quello che proverei per primo. NULL è una macro piuttosto standard e dovrebbe essere definita dappertutto.

In questo momento, il tuo problema è che C ++ non consente cast automatici da void * ad altri tipi di puntatori come fa C.

Da Riferimento C ++ :

  

In C ++, NULL si espande a 0 o 0L.

Se non funziona, esegui una sostituzione globale nella libreria: da NULL a LIBDEFINEDNULL o qualcosa del genere. In questo modo manterrai intatto il codice della libreria ed eviterai la collisione di macro.

Altri suggerimenti

Hai accesso a quella fonte di librerie? Se è così, penso che una ricerca e la sostituzione sul loro codice sia in ordine. (Sostituisci il loro NULL con LIBNAME_NULL o qualcosa di simile.) Se questa non è semplicemente un'opzione, consiglierei di usare 0 nel tuo codice anziché NULL.

Sono curioso, però: quali problemi sta causando? Non stanno cambiando il valore di null, ma solo il casting predefinito.

Uno dei tuoi commenti dice che hai considerato di ridefinirlo da solo, ma non sai a cosa ridefinirlo.

Molte implementazioni definiranno NULL in questo modo:

#undef NULL

#ifdef __cplusplus
#define NULL 0
#else
#define NULL ((void*)0)
#endif

Questo perché in C ha senso averlo come puntatore vuoto, perché è un tipo di puntatore che può essere implicitamente trasmesso ad altri tipi.

C ++ non lo consente (il che causa i tuoi problemi), ma l'utilizzo di 0 invece di NULL funziona.

Penso che in tutte le versioni recenti, GCC lo definirà in __null , che è un'estensione non portatile.

L'approccio più generico sarebbe quello di concludere le inclusioni offensive e archiviare e ripristinare la definizione precedente delle macro. Questo, tuttavia, dipende dal compilatore.
Ecco come potresti farlo con VC:

#pragma push_macro("NULL")
#include <offendinglib.h>
#pragma pop_macro("NULL")

In alternativa, imposta la macro su ciò che ti serve in seguito:

#include <offendinglib.h>
#undef NULL
#define NULL 0

Sì, devi solo lanciare in modo appropriato:

Generic(std::string name, Json::Value *config, int type,
    LCDBase *lcd = (LCDBase *)NULL);
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top