1

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

編集:わかりました、キャストは明示的に機能しますが、関数ポインターをキャストするにはどうすればよいですか?

4

5 に答える 5

5

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

今のところ、あなたの問題は、C++がCvoid *のように他のポインタ型への自動キャストを許可していないことです。

C ++リファレンスから:

C ++では、NULLは0または0Lに拡張されます。

それでも問題が解決しない場合は、ライブラリでグローバル置換を実行してNULLくださいLIBDEFINEDNULL。そうすれば、ライブラリコードをそのまま維持し、マクロの衝突を回避できます。

于 2009-11-30T00:50:29.580 に答える
3

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

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

于 2009-11-30T00:50:55.877 に答える
3

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

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

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

#include <offendinglib.h>
#undef NULL
#define NULL 0
于 2009-11-30T00:52:11.497 に答える
3

あなたのコメントの1つは、自分で再定義することを検討したと言っていますが、何に再定義するかわかりません。

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

#undef NULL

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

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

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

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

于 2009-11-30T00:59:25.517 に答える
-1

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

Generic(std::string name, Json::Value *config, int type,
    LCDBase *lcd = (LCDBase *)NULL);
于 2009-11-30T00:55:21.947 に答える