【问题标题】:Why am I getting these linker errors?为什么我会收到这些链接器错误?
【发布时间】:2010-10-10 19:05:31
【问题描述】:

我收到以下链接器错误:

Error   1   error LNK2001: unresolved external symbol "public: __thiscall AguiEvent<class AguiEmptyEventArgs>::AguiEvent<class AguiEmptyEventArgs>(void)" (??0?$AguiEvent@VAguiEmptyEventArgs@@@@QAE@XZ)    AguiWidgetBase.obj
Error   2   error LNK2001: unresolved external symbol "public: void __thiscall AguiEvent<class AguiEmptyEventArgs>::call(class AguiEmptyEventArgs)" (?call@?$AguiEvent@VAguiEmptyEventArgs@@@@QAEXVAguiEmptyEventArgs@@@Z)  AguiWidgetBase.obj
Error   3   error LNK2001: unresolved external symbol "public: __thiscall AguiEvent<class AguiControlEventArgs>::AguiEvent<class AguiControlEventArgs>(void)" (??0?$AguiEvent@VAguiControlEventArgs@@@@QAE@XZ)  AguiWidgetBase.obj
Error   4   error LNK2001: unresolved external symbol "public: void __thiscall AguiEvent<class AguiControlEventArgs>::call(class AguiControlEventArgs)" (?call@?$AguiEvent@VAguiControlEventArgs@@@@QAEXVAguiControlEventArgs@@@Z)  AguiWidgetBase.obj
Error   5   fatal error LNK1120: 4 unresolved externals C:\Users\Josh\Documents\Visual Studio 2008\Projects\Agui\STATIC Release\Agui.exe

我有 AguiEventArgs.h,其中有:

class AguiWidgetBase;

class AguiEmptyEventArgs {
public:
    AguiEmptyEventArgs();
};

class AguiMouseEventArgs {
    AguiPoint position;
    int mouseWheelChange;
    AguiMouseButtonEnum button;
public:
    AguiPoint getPosition() const;
    int getMouseWheelChange() const;
    AguiMouseButtonEnum getButton() const;
    int getX() const;
    int getY() const;
    AguiMouseEventArgs();
    AguiMouseEventArgs(const AguiPoint &position,
        int mouseWheelChange, AguiMouseButtonEnum button);
};

class AguiKeyEventArgs {
    AguiKeyEnum key;
    AguiKeyModifierEnum modKey;
    bool isAlt;
    bool isControl;
    bool isShift;
public:
    bool getAlt() const;
    bool getControl() const;
    bool getShift() const;
    AguiKeyEnum getKey() const;
    AguiKeyModifierEnum getModifierKeyFlags() const;
    AguiKeyEventArgs();
    AguiKeyEventArgs(AguiKeyEnum key, AguiKeyModifierEnum modKey);
};

class AguiControlEventArgs {
    AguiWidgetBase* control;
public:
    AguiWidgetBase* getControl() const;
    AguiControlEventArgs();
    AguiControlEventArgs(AguiWidgetBase* control);
};

我已经仔细检查并定义了所有这些。

我的 Agui 活动在这里:

template <typename T>
class AguiEvent {
void (*onEvent)(T arg);
public:
void setHandler(void (*eventProc)(T arg));
void removeHandler();
void call(T arg);
AguiEvent();
};

它的定义:

template <typename T>
void AguiEvent<T>::setHandler( void (*eventProc)(T arg) )
{
    onEvent = eventProc;
}


template <typename T>
void AguiEvent<T>::removeHandler()
{
    onEvent = 0;
}


template <typename T>
void AguiEvent<T>::call(T arg)
{
    if(onEvent)
        onEvent(arg);
}

template <typename T>
AguiEvent<T>::AguiEvent()
{
    onEvent = 0;
}

它是这样使用的:

 AguiEvent<AguiEmptyEventArgs> eventThemeChanged;
    AguiEvent<AguiControlEventArgs> eventChildControlAdded;
    AguiEvent<AguiControlEventArgs> eventChildControlRemoved;

例如:

void AguiWidgetBase::addChildControl( AguiWidgetBase *control )
{
    onAddChildControl(control);
    eventChildControlAdded.call(AguiControlEventArgs(control));

}

谢谢

【问题讨论】:

    标签: c++ visual-studio linker


    【解决方案1】:

    您需要在头文件中定义模板类函数,不能将它们放在单独的 .cpp 文件中(甚至不要考虑使用支持不佳的 export 关键字来做到这一点)。

    这是因为编译器每次实例化时都需要模板的源代码:它必须为每个模板实例化生成单独的代码。链接器足够聪明,可以确保在最终的可执行文件中只使用每个实例化的一个副本,即使同一个模板在不同的翻译单元中被实例化多次。

    【讨论】:

    • export 不是非标准的,至少在今天是这样。其他都同意
    • @Armen:哎呀,你是对的;我稍微改变了措辞以反映这一点。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-10-24
    • 2011-11-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多