1


0

ライブラリはNULLを再定義します

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);

編集:[OK]を、明示的にキャストが動作しますが、どのように関数ポインタにキャストしますか?

5 Answer


5


その定義なしでライブラリを再構築できますか? それが私が最初に試すことです。 「NULL」はかなり標準的なマクロであり、どこでも定義されていると仮定する必要があります。

現在、あなたの問題は、C ++が `void *`からCのような他のポインタ型への自動キャストを許可していないことです。

C++ Referenceから:

_ C ++では、NULLは0または0Lに展開されます。 _

それが機能しない場合は、ライブラリでグローバル置換を実行するだけです: NULL`から LIBDEFINEDNULL`または何か。 そうすれば、ライブラリコードをそのまま保持し、マクロの衝突を回避できます。


3


そのライブラリのソースにアクセスできますか? もしそうなら、彼らのコードでの検索と置換が適切だと思います。 (それらのNULLをLIBNAME_NULLまたは同様のものに置き換えます。)それが単にオプションではない場合、NULLの代わりにコードで0を使用することをお勧めします。

しかし、私は興味があります:それはどのような問題の原因ですか? nullの値は変更せず、デフォルトのキャストのみを変更します。


3


最も一般的なアプローチは、問題のあるインクルードと、マクロの以前の定義の_store_と_restore_をまとめることです。 ただし、これはコンパイラに依存します。 +これは、VCを使用して行う方法です。

#pragma push_macro("NULL")
#include
#pragma pop_macro("NULL")

または、マクロを後で必要なものに設定します。

#include
#undef NULL
#define NULL 0


3


コメントの1つに、自分で再定義することを検討したが、何を再定義すべきかわからないということがあります。

多くの実装は、次のようにNULLを定義します。

#undef NULL

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

これは、Cでは暗黙的に他の型にキャストできるポインター型であるため、Cでvoidポインターとして使用するのが理にかなっているためです。

C ++はこれを許可しません(これが問題を引き起こしています)が、 NULL`の代わりに 0`を使用することはできます。

最近のすべてのバージョンで、GCCは実際にそれを `__null`に定義しますが、これは移植性のない拡張です。


-1


はい、適切にキャストする必要があります。

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