【问题标题】:Undefined reference未定义参考
【发布时间】:2009-11-13 05:44:49
【问题描述】:

我收到此链接器错误。我知道一种解决方法,但它困扰着我,因为项目的另一部分连接良好,而且设计几乎相同。

首先,我有命名空间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]

编辑:顺便说一下,TextHistogramDrawTextGifDraw 也遇到了同样的错误。 TextIconDraw 其他都很好。

【问题讨论】:

  • 你是如何在库中链接的?您使用的是哪个编译器/链接器?
  • 你能发布包含“WidgetBignums.h”的代码文件吗..也许是WidgetBignums.cpp?
  • @Andrew:我包括了课程本身。如果您还需要其他东西,请告诉我。

标签: c++ linker-errors


【解决方案1】:

LCD::TextBignumsDraw() 的定义在哪里?这就是链接器似乎在抱怨的问题。不是声明,而是函数的实际定义。

当您将声明移出命名空间 LCD 时,事情开始起作用这一事实表明 TextBignumsDraw() 的定义位于全局命名空间中,而不是 LCD 命名空间中。

这个(在一些 .cpp 文件中):

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

需要包裹在一个

namespace LCD {

}

阻止。

【讨论】:

  • 我将命名空间添加到函数的签名中。奇怪的是,没有它其他功能也能正常工作。感谢您的推动。
【解决方案2】:

尝试删除“使用命名空间 LCD”,并将第 66 行更改为:

Draw = LCD::TextBignumsDraw;

这更明确,这可能有助于链接器理解您的要求。

此外,您永远不应该在头文件中说“使用命名空间任何东西”。它将该名称空间中的所有内容提升到该标题的每个用户的全局空间中。这几乎完全破坏了首先拥有命名空间的价值。您应该在实际可行的最窄范围内将这样的东西吊起来。有时我将“使用命名空间 foo”放在单个函数的顶部,例如,如果这是给定 .cpp 文件中命名空间中位的唯一用户。

【讨论】:

    猜你喜欢
    • 2014-12-16
    • 2015-01-14
    • 2023-03-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-12-02
    • 2020-06-03
    • 2011-09-11
    相关资源
    最近更新 更多