2009-11-30 6 views
1

NULL을 재정의하는 라이브러리를 사용하고 있습니다. 내 프로그램의 다른 부분에 문제가 발생합니다. 내가 뭘 할 수 있는지 잘 모르겠다. 어떤 생각? 내 프로그램은 C++이고, 라이브러리는 C입니다.라이브러리가 NULL을 다시 정의합니다.

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

편집 : 좋아, 주조 명시 적으로 작동을하지만 어떻게 내가 함수에 대한 내느냐 바늘?

+0

NULL을 정의한 후 포함 시키셨습니까? –

+0

무엇을 다시 정의해야할지 모르겠습니다. ORG_NULL에 NULL을 저장하고 libvisual을 포함하여 NULL을 다시 정의하려고 시도했지만 작동하지 않았습니다. – Scott

+0

사실, 그냥 NULL을 적절하게 캐스팅해야한다고 생각합니다. – Scott

답변

5

정의하지 않고 라이브러리를 다시 빌드 할 수 있습니까? 그게 내가 먼저 시도 할거야. NULL은 꽤 표준적인 매크로이며 어디에나 정의되어 있다고 가정해야합니다.

지금 당장의 문제는 C++이 void *에서 C와 같은 다른 포인터 유형으로의 자동 형 변환을 허용하지 않는다는 것입니다. C++ Reference에서

:

C++에서

, NULL은 0 또는 0L에 하나를 확장합니다.

문제가 해결되지 않으면, 단지 글로벌 라이브러리에서 대체 할 : NULLLIBDEFINEDNULL 또는 뭔가. 그렇게하면 라이브러리 코드가 손상되지 않고 매크로 충돌을 피할 수 있습니다.

+0

나는 그것에 대해 생각했지만 라이브러리는 내부적 인 이유로 라이브러리를 다시 정의 할 가능성이 높습니다. 그게 내가 시도하는 마지막 일이 될거야. 나는 적절한 캐스팅을 시도 할 것이다. – Scott

+4

나는 lib의 IRC 채널에서 누군가와 이야기를 나눴다. 그는 NULL이 재정의 된 이유를 잘 모릅니다. 나는 도서관으로 가서 라이브러리를 제거하고 잘 컴파일했다. – Scott

+0

매력적인. 그 사람은 DailyWTF에 속해 있습니다! 업데이트 주셔서 감사합니다! – Toji

3

해당 라이브러리 출처에 대한 액세스 권한이 있습니까? 그렇다면 검색 및 코드 교체가 순서대로 이루어 졌다고 생각합니다. (NULL을 LIBNAME_NULL 또는 유사한 것으로 대체하십시오.) 단순히 옵션이 아니라면 NULL 대신 코드를 0으로 사용하는 것이 좋습니다.

나는 궁금한데, 어떤 문제가 그것입니까? 그들은 null의 값을 변경하지 않고 기본 캐스팅 만 변경합니다.

+2

C에서는 void *에서 모든 포인터 유형으로 암시 적으로 캐스트 할 수 있습니다. C++에서는 그렇게 할 수 없습니다. 라이브러리가 그것을 ((void *) 0)으로 정의하기 때문에 그는 C++ 코드에 문제가있다. – asveikau

+0

+1 아,이 아이디어가 이미 있습니다. –

+0

아, 좋은 점 asveikau. 나는 최근에 일부 C 인터페이스를 해왔다. 그래서 나는 그 사고 방식에 좀 머물렀다. :) – Toji

3

가장 일반적인 방법은 및 매크로 이전 정의를 복원 잘못된 포함 저장소를 마무리하는 것입니다. 그러나 이것은 컴파일러에 종속적입니다.
이것은 당신이 VC와 함께 할 수있는 방법입니다 :

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

#define NULL이 아님 0 – Joshua

+0

예, 편집 John에게 감사드립니다. –

-1

예, 당신이 적절하게 캐스팅 할 필요가 단지 않습니다

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

, 당신이 이후로 그것을 필요로 매크로를 설정합니다

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

당신은 캐스트를 필요로하지 않아야합니다. C++에서'NULL'을'T *'로 바꾸십시오. –

+0

gf이지만이 라이브러리는 NULL을 다시 정의하므로 암시 적으로 변환되지 않습니다. – Scott

+0

나쁜 생각. NULL 매크로의 포인트가 누락됩니다. NULL을 던지는 코드를 작성하면 사람들은 코드를보고 바보라고 생각합니다. :-) – asveikau

3

귀하의 의견 중 하나는 귀하가 직접 재정의하는 것을 고려했으나이를 재정의해야 할 대상을 모른다고합니다.

구현의 많은 같이 NULL을 정의합니다 :

#undef NULL 

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

이것은 C에서, 그것은 무효 포인터로 그것을 가지고 의미가 있기 때문에, 그것은 암시 적으로 다른 캐스트 할 수있는 포인터 타입이기 때문에 유형.

C++은이 문제를 일으키지 않지만, NULL 대신 0을 사용합니다.

나는 모든 최신 버전에서 GCC가 이것을 실제로 휴대 성이없는 확장자 인 __null으로 정의 할 것이라고 생각합니다.