2009-11-13 13 views
0

이 링커 오류가 발생합니다. 나는 그 주위에 방법을 안다. 그러나 그것은 프로젝트의 다른 부분이 잘 연결되어 있고 거의 동일하게 디자인 되었기 때문에 나를 괴롭 히고있다.정의되지 않은 참조

먼저 네임 스페이스 LCD이 있습니다. 그럼 난 두 개의 별도의 파일, LCDText.h 및 LCDGraphic.h 있습니다.

LCDText.h :

//[snip] 
void TextDraw(Widget *w); 

void TextBarDraw(Widget *w); 

void TextHistogramDraw(Widget *w); 

void TextIconDraw(Widget *w); 

void TextBignumsDraw(Widget *w); 

void TextGifDraw(Widget *w); 

}; // End namespace 

LCDGraphic.h :

//[snip] 
using namespace LCD; 

extern void TextBignumsDraw(Widget *w); 
extern void GraphicBignumsDraw(Widget *w); 

template <class T> 
WidgetBignums<T>::WidgetBignums(Generic<T> *v, std::string n, Json::Value *section, 
    int row, int col) : Widget(n, section, row, col, 
    WIDGET_TYPE_BIGNUMS | WIDGET_TYPE_RC | WIDGET_TYPE_SPECIAL) { 

    if(v->GetType() == LCD_TEXT) 
     Draw = TextBignumsDraw; // Line 66 
    else if(v->GetType() == LCD_GRAPHIC) 
     Draw = GraphicBignumsDraw; 
    else 
     Draw = NULL; 
//[snip] 

그리고 난 다음 링커 오류 :

//[snip] 
void GraphicDraw(Widget *w); 

void GraphicIconDraw(Widget *w); 

void GraphicBarDraw(Widget *w); 

void GraphicHistogramDraw(Widget *w); 

void GraphicBignumsDraw(Widget *w); 

void GraphicGifDraw(Widget *w); 

}; // End namespace 

그리고 WidgetBignums.h에서

내가 가진

LCDControl.o: In function `WidgetBignums': 
/home/starlon/Projects/LCDControl/WidgetBignums.h:66: undefined reference to `LCD::TextBignumsDraw(LCD::Widget*)' 

이제 문제를 해결하는 한 가지 방법이 있지만 마음에 들지 않습니다. LCD::TextBignumsDrawLCD 네임 스페이스 외부로 이동할 수 있으며 제대로 작동합니다. 이상하게도 링커는 LCD::GraphicBignumsDraw을 봅니다. 모든 단서?

편집 : Fedora 11에서 gcc 4.4.1-2를 사용하고 있습니다. SCons를 사용하여 컴파일하십시오.

편집 : 여기에 WidgetBignums가 있으며, Draw이 표시됩니다.

template <class T> 
class WidgetBignums : public Widget { 
    Generic<T> *visitor_; 
    std::vector<char> FB_; 
    std::vector<char> ch_; 
    int min_; 
    int max_; 
    int update_; 
    int layer_; 
    Property *expression_; 
    Property *expr_min_; 
    Property *expr_max_; 

    QTimer *timer_; 

    void (*Draw)(Widget *); 

    public: 
    WidgetBignums(Generic<T> *visitor, std::string name, Json::Value *section, int row, int col); 
    ~WidgetBignums(); 
    void TextScroll() {}; 
    void SetupChars(); 
    void Update(); 
    void Start(); 
    void Stop(); 
    std::vector<char> GetFB() { return FB_; } 
    std::vector<char> GetCh() { return ch_; } 
    Generic<T> *GetVisitor() { return visitor_; } 
}; 

편집 : 여기에 TextBignumsDraw의 서명이 있습니다.

//[snip] 
void TextBignumsDraw(Widget *w) { 
//[snip] 

편집 : 덧붙여, 나뿐만 아니라 TextHistogramDrawTextGifDraw에 대해 동일한 오류를 받고 있어요. TextIconDraw 및 기타 괜찮습니다. 떨어

+0

라이브러리에서 어떻게 연결하고 있습니까? 어떤 컴파일러/링커를 사용하고 있습니까? – LeopardSkinPillBoxHat

+0

"WidgetBignums.h"가 포함 된 코드 파일을 게시 할 수 있습니까? 아마도 WidgetBignums.cpp입니까? –

+0

@Andrew : 클래스 자체를 포함했습니다. 다른 뭔가가 필요하면 말해줘. – Scott

답변

3

LCD::TextBignumsDraw()의 정의는 어디에 있습니까? 이것이 링커가 불평하는 것입니다. 선언이 아니라 기능의 실제 정의.

네임 스페이스에서 선언을 이동할 때 LCD 작업 시작이 TextBignumsDraw()에 대한 정의가 LCD 네임 스페이스가 아닌 전역 네임 스페이스에 있음을 나타냅니다.

이것은 (일부.CPP 파일) :

void TextBignumsDraw(Widget *w) { 
    // ... 
} 

이 필요가

namespace LCD { 

} 

블록에 싸여있다.

+0

함수의 서명에 네임 스페이스를 추가했습니다. 이상한 다른 기능은 그것없이 잘 작동합니다. 뉘앙스 주셔서 감사. – Scott

1

시도에 그 라인 (66)을 "네임 스페이스의 LCD를 사용하여"변경 : 링커가 당신이 요구하는지 이해하는 데 도움이 될 수 있습니다 더 명시 적입니다

Draw = LCD::TextBignumsDraw; 

.

게다가 헤더 파일에서 "namespace Anything"을 사용해서는 안됩니다. 해당 네임 스페이스의 모든 것을 해당 헤더의 모든 사용자를위한 글로벌 공간으로 끌어 올립니다. 이는 거의 처음부터 네임 스페이스를 갖는 것의 가치를 완전히 파괴합니다. 실용적인 가장 좁은 범위에서 이런 일을 꺼내야합니다. 때때로 나는 하나의 함수의 최상위에 "using namespace foo"를 넣습니다. 예를 들어 주어진 .cpp 파일 내의 네임 스페이스에있는 비트의 유일한 사용자 인 경우입니다.