我收到此链接器错误。我知道解决这个问题的方法,但它让我烦恼,因为该项目的另一部分链接很好而且它的设计几乎相同。
首先,我有名称空间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::TextBignumsDraw
移到LCD
命名空间之外,它可以正常工作。奇怪的是,链接器看到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]
编辑:顺便说一句,我也为TextHistogramDraw
和TextGifDraw
收到同样的错误。 TextIconDraw
和其他人都很好。
答案 0 :(得分:3)
LCD::TextBignumsDraw()
的定义在哪里?这就是链接器似乎在抱怨的东西。不是声明,而是函数的实际定义。
当你从名称空间LCD
中移出声明时,开始工作的事实表明TextBignumsDraw()
的定义在全局命名空间中,而不是LCD
命名空间。
这(在某些.cpp文件中):
void TextBignumsDraw(Widget *w) {
// ...
}
需要包装在
中namespace LCD {
}
块。
答案 1 :(得分:1)
尝试删除“using namespace LCD”,并将该行66更改为:
Draw = LCD::TextBignumsDraw;
这更明确,这可能有助于链接器了解您的要求。
此外,你永远不应该在头文件中说“使用命名空间任何东西”。它将该命名空间中的所有内容提升到该标头的每个用户的全局空间中。这几乎完全破坏了首先拥有命名空间的价值。你应该在最实际的范围内提升这样的东西。有时我会在单个函数的顶部放置“using namespace foo”,例如,如果它是给定.cpp
文件中命名空间中位的唯一用户。