<div dir="ltr">I am struggling with an issue while I am using external .h files in my project.<br>
<br>
I am using Qt5 with MSVC2012. In my main file, I am including a header<br>
file from a KDE application. I put some INCLUDEPATH in the .pro file<br>
to link correctly.<br>
<br>
The piece of code I am in trouble with is the following:<br>
<br><blockquote style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex" class="gmail_quote">
main.cpp<br>
...<br>
#include <Doc.h><br>
<br>
int main(int argc, char *argv[])<br>
...<br></blockquote>
<br>
The Doc.h belongs to the KDE application source code. Including that<br>
file includes many other files in several directories in the KDE<br>
application source code.<br>
<br>
Currently, the KUndo2Stack.h and the KUndo2Stack.cpp files are the<br>
files I am struggling with since three days now.<br>
<br>
When I run QMake and compile, I get a link 2001 errors due to<br>
unresolved externals with virtual functions in the KUndo2QStack class<br>
defined and implemented in those files. Here is an extract:<br>
<br><blockquote style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex" class="gmail_quote">
#ifndef QT_NO_UNDOSTACK<br>
<br>
class KUNDO2_EXPORT KUndo2QStack : public QObject<br>
{<br>
    Q_OBJECT<br>
//    Q_DECLARE_PRIVATE(</blockquote><div id=":248" class=""><blockquote>KUndo2QStack)<br>
    Q_PROPERTY(bool active READ isActive WRITE setActive)<br>
    Q_PROPERTY(int undoLimit READ undoLimit WRITE setUndoLimit)<br>
<br>
public:<br>
    explicit KUndo2QStack(QObject *parent = 0);<br>
    virtual ~KUndo2QStack();<br>
    void clear();<br>
<br>
    void push(KUndo2Command *cmd);<br>
<br>
    bool canUndo() const;<br>
    bool canRedo() const;<br>
    QString undoText() const;<br>
    QString redoText() const;<br>
<br>
    int count() const;<br>
    int index() const;<br>
    QString actionText(int idx) const;<br>
    QString text(int idx) const;<br>
<br>
#ifndef QT_NO_ACTION<br>
    QAction *createUndoAction(QObject *parent) const;<br>
    QAction *createRedoAction(QObject *parent) const;<br>
#endif // QT_NO_ACTION<br>
<br>
    bool isActive() const;<br>
    bool isClean() const;<br>
    int cleanIndex() const;<br>
<br>
    void beginMacro(const QString &text);<br>
    void endMacro();<br>
<br>
    void setUndoLimit(int limit);<br>
    int undoLimit() const;<br>
<br>
    const KUndo2Command *command(int index) const;<br>
<br>
public Q_SLOTS:<br>
    void setClean();<br>
    virtual void setIndex(int idx);<br>
    virtual void undo();<br>
    virtual void redo();<br>
    void setActive(bool active = true);<br>
<br>
Q_SIGNALS:<br>
    void indexChanged(int idx);<br>
    void cleanChanged(bool clean);<br>
    void canUndoChanged(bool canUndo);<br>
    void canRedoChanged(bool canRedo);<br>
    void undoTextChanged(const QString &undoActionText);<br>
    void redoTextChanged(const QString &redoActionText);<br>
<br>
private:<br>
    // from QUndoStackPrivate<br>
    QList<KUndo2Command*> m_command_list;<br>
    QList<KUndo2Command*> m_macro_stack;<br>
    int m_index;<br>
    int m_clean_index;<br>
    KUndo2Group *m_group;<br>
    int m_undo_limit;<br>
<br>
    // also from QUndoStackPrivate<br>
    void setIndex(int idx, bool clean);<br>
    bool checkUndoLimit();<br>
<br>
    Q_DISABLE_COPY(KUndo2QStack)<br>
    friend class KUndo2Group;<br>
};<br>
<br>
class KUNDO2_EXPORT KUndo2Stack : public KUndo2QStack<br>
{<br>
public:<br>
    explicit KUndo2Stack(QObject *parent = 0);<br>
<br>
    // functions from KUndoStack<br>
    QAction* createRedoAction(KActionCollection* actionCollection,<br>
const QString& actionName = QString());<br>
    QAction* createUndoAction(KActionCollection* actionCollection,<br>
const QString& actionName = QString());<br>
};<br>
<br>
#endif // QT_NO_UNDOSTACK<br>
<br>
Note that the unresolved links occur only for virtual functions. Those<br>
functions are implemented as it follows:<br>
<br>
KUndo2QStack::~KUndo2QStack()<br>
{<br>
#ifndef QT_NO_UNDOGROUP<br>
    if (m_group != 0)<br>
        m_group->removeStack(this);<br>
#endif<br>
    clear();<br>
}<br>
<br>
void KUndo2QStack::undo()<br>
{<br>
    if (m_index == 0)<br>
        return;<br>
<br>
    if (!m_macro_stack.isEmpty()) {<br>
        qWarning("KUndo2QStack::undo(): cannot undo in the middle of a macro");<br>
        return;<br>
    }<br>
<br>
    int idx = m_index - 1;<br>
    <a href="http://m_command_list.at" target="_blank">m_command_list.at</a>(idx)->undo();<br>
    setIndex(idx, false);<br>
}<br>
<br>
void KUndo2QStack::redo()<br>
{<br>
    if (m_index == m_command_list.size())<br>
        return;<br>
<br>
    if (!m_macro_stack.isEmpty()) {<br>
        qWarning("KUndo2QStack::redo(): cannot redo in the middle of a macro");<br>
        return;<br>
    }<br>
<br>
    <a href="http://m_command_list.at" target="_blank">m_command_list.at</a>(m_index)->redo();<br>
    setIndex(m_index + 1, false);<br>
}<br>
<br>
void KUndo2QStack::setIndex(int idx)<br>
{<br>
    if (!m_macro_stack.isEmpty()) {<br>
        qWarning("KUndo2QStack::setIndex(): cannot set index in the<br>
middle of a macro");<br>
        return;<br>
    }<br>
<br>
    if (idx < 0)<br>
        idx = 0;<br>
    else if (idx > m_command_list.size())<br>
        idx = m_command_list.size();<br>
<br>
    int i = m_index;<br>
    while (i < idx)<br>
        <a href="http://m_command_list.at" target="_blank">m_command_list.at</a>(i++)->redo();<br>
    while (i > idx)<br>
        <a href="http://m_command_list.at" target="_blank">m_command_list.at</a>(--i)->undo();<br>
<br>
    setIndex(idx, false);<br>
}<br></blockquote>
<br>
I have turned this question upside down looking for answers on the web<br>
and the only time I got something was when I deleted the word virtual<br>
off all the related functions. It cancelled the errors but I got an<br>
unresolved link2019 error with the destructor of the class KUndo2Stack<br>
(see the code above). The destructor I am talking about is the default<br>
one, you won't see any definition or implementation of it.<br>
<br>
I need some help to understand what is really going on and how to fix it.<br>
<br>
The exact error messages are:<br>
<br><blockquote style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex" class="gmail_quote">
main.obj:-1: error: LNK2001: unresolved external symbol "public:<br>
virtual struct QMetaObject const * __cdecl<br>
KUndo2QStack::metaObject(void)const "<br>
(?metaObject@KUndo2QStack@@UEBAPEBUQMetaObject@@XZ)<br>
<br>
main.obj:-1: error: LNK2001: unresolved external symbol "public:<br>
virtual void * __cdecl KUndo2QStack::qt_metacast(char const *)"<br>
(?qt_metacast@KUndo2QStack@@UEAAPEAXPEBD@Z)<br>
<br>
main.obj:-1: error: LNK2001: unresolved external symbol "public:<br>
virtual int __cdecl KUndo2QStack::qt_metacall(enum<br>
QMetaObject::Call,int,void * *)"<br>
(?qt_metacall@KUndo2QStack@@UEAAHW4Call@QMetaObject@@HPEAPEAX@Z)<br>
<br>
main.obj:-1: error: LNK2001: unresolved external symbol "public:<br>
virtual void __cdecl KUndo2QStack::setIndex(int)"<br>
(?setIndex@KUndo2QStack@@UEAAXH@Z)<br>
<br>
main.obj:-1: error: LNK2001: unresolved external symbol "public:<br>
virtual void __cdecl KUndo2QStack::undo(void)"<br>
(?undo@KUndo2QStack@@UEAAXXZ)<br>
<br>
main.obj:-1: error: LNK2001: unresolved external symbol "public:<br>
virtual void __cdecl KUndo2QStack::redo(void)"<br>
(?redo@KUndo2QStack@@UEAAXXZ)<br>
<br>
main.obj:-1: error: LNK2019: unresolved external symbol<br>
"__declspec(dllimport) public: virtual __cdecl<br>
KUndo2Stack::~KUndo2Stack(void)" (__imp_??1KUndo2Stack@@UEAA@XZ)<br>
referenced in function "public: virtual void * __cdecl<br>
KUndo2Stack::`scalar deleting destructor'(unsigned int)"<br>
(??_GKUndo2Stack@@UEAAPEAXI@Z)<br>
<br>
debug\whitehall_0_2.exe:-1: error: LNK1120: 7 unresolved externals</blockquote><div><br></div><div><i>Patrik GWET </i><br></div></div></div>