2009-11-13 87 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] 
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我:

//[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] 

我得到下面的连接错误:

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

现在有一种方法来解决它,但我不喜欢它。我可以在LCD命名空间之外移动LCD::TextBignumsDraw,它可以工作。奇怪的是,链接器看到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 2009-11-13 05:51:08

+0

你可以发布包含“WidgetBignums.h”的代码文件..也许WidgetBignums.cpp? – 2009-11-13 05:53:15

+0

@Andrew:我包括这个类。告诉我你是否需要别的东西。 – Scott 2009-11-13 05:58:40

回答

3

LCD::TextBignumsDraw()的定义是什么?这是链接器似乎在抱怨的内容。不是声明,而是函数的实际定义。

事实上,当您将声明从命名空间LCD移出时,表示TextBignumsDraw()的定义位于全局名称空间中,而不是LCD名称空间中。

这(在一些情况下。CPP文件):

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

需要被包裹在一个

namespace LCD { 

} 

块。

+0

我将该命名空间添加到该函数的签名中。奇怪的是,没有它的其他功能正常工作。感谢您的推动。 – Scott 2009-11-13 06:19:37

1

尝试去掉了“使用命名空间LCD”,并更改了该行66:

Draw = LCD::TextBignumsDraw; 

这更加明确,这可以帮助了解连接你问什么。

另外,你不应该在头文件中说“using namespace Anything”。它将该名称空间中的所有内容都提升到全局空间中,以便每个用户使用该头文件。这几乎完全破坏了首先拥有名称空间的价值。你应该在最实际的范围内把这样的事情提出来。有时候我会在单个函数的顶部放置“using namespace foo”,例如,如果这是给定.cpp文件中命名空间中唯一位的用户。