Вопрос

Я работаю с библиотекой, которая переопределяет NULL. Это вызывает некоторые проблемы с другими частями моей программы. Я не уверен, что я могу с этим поделать. Любая идея? Моя программа на C ++, библиотека на C .

#ifdef NULL
#undef NULL
#endif

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

О, и он выдает эти ошибки:

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

Вот первый:

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

Редактировать. Хорошо, приведение в явном виде работает, но как преобразовать указатель на функцию?

Это было полезно?

Решение

Можете ли вы перестроить библиотеку без этого определения? Это то, что я попробую в первую очередь. NULL - довольно стандартный макрос, и предполагается, что он определен везде.

В данный момент ваша проблема в том, что C ++ не разрешает автоматическое приведение из void * к другим типам указателей, как это делает C.

Из Справочника по C ++ :

  

В C ++ NULL расширяется до 0 или 0L.

Если это не сработает, просто выполните глобальную замену в библиотеке: NULL на LIBDEFINEDNULL или что-то в этом роде. Таким образом вы сохраните код библиотеки и избежите столкновения макросов.

Другие советы

У вас есть доступ к этому источнику библиотек? Если это так, я думаю, что поиск и замена по их коду в порядке. (Замените их NULL на LIBNAME_NULL или что-то подобное.) Если это просто не вариант, я бы рекомендовал использовать 0 в вашем коде вместо NULL.

Мне любопытно: какие проблемы это вызывает? Они не изменяют значение null, только приведение по умолчанию.

В одном из ваших комментариев говорится, что вы рассматривали возможность его переопределения самостоятельно, но не знаете, к чему его переопределить.

Многие реализации будут определять NULL следующим образом:

#undef NULL

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

Это потому, что в C имеет смысл иметь его как пустой указатель, потому что это тип указателя, который можно неявно приводить к другим типам.

C ++ не разрешает этого (что вызывает ваши проблемы), но использование 0 вместо NULL работает.

Я думаю, что во всех последних версиях GCC определит его как __ null , которое является непереносимым расширением.

Наиболее общий подход заключается в том, чтобы обернуть оскорбительные включения, сохранить и восстановить предыдущее определение макроса. Это, однако, зависит от компилятора.
Вот как вы могли бы сделать это с VC:

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

В качестве альтернативы, установите макрос таким, каким он должен быть после вас:

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

Да, вам просто нужно правильно разыграть:

Generic(std::string name, Json::Value *config, int type,
    LCDBase *lcd = (LCDBase *)NULL);
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top