0

このリンカ エラーが発生します。私はそれを回避する方法を知っていますが、プロジェクトの別の部分がうまくリンクしていて、ほとんど同じように設計されているため、私を悩ませています。

まず、名前空間がありますLCD。それから、LCDText.h と LCDGraphic.h という 2 つの別個のファイルがあります。

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*)'

これを修正する1つの方法がありますが、私はそれが好きではありません. 名前空間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]

編集:ちなみに、私はTextHistogramDrawandでも同じエラーが発生しTextGifDrawています。TextIconDrawそして他は大丈夫です。

4

2 に答える 2

3

の定義はどこにありLCD::TextBignumsDraw()ますか? それがリンカが不平を言っているようです。宣言ではなく、関数の実際の定義です。

宣言を名前空間の外に移動するとLCD動作が開始されるという事実は、 の定義がTextBignumsDraw()名前空間ではなくグローバル名前空間にあることを示していLCDます。

これ(一部の.cppファイル内):

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

でラップする必要があります

namespace LCD {

}

ブロック。

于 2009-11-13T06:13:59.310 に答える
1

「using namespace LCD」を削除してみて、その 66 行目を次のように変更します。

Draw = LCD::TextBignumsDraw;

これはより明示的であり、リンカーが何を求めているのかを理解するのに役立ちます。

また、ヘッダー ファイルで「名前空間 Anything を使用する」とは絶対に言ってはいけません。その名前空間のすべてを、そのヘッダーのすべてのユーザーのグローバル空間に引き上げます。それは、そもそも名前空間を持つことの価値をほぼ完全に破壊します。このようなものは、実用的な最も狭い範囲で持ち上げる必要があります。たとえば、特定のファイル内の名前空間のビットの唯一のユーザーである場合など、単一の関数の先頭に「名前空間 foo を使用する」を配置することがあり.cppます。

于 2009-11-13T06:12:51.270 に答える