[SOLVED] Problem Linking after changing project to dynamic rather than static.



  • I am pretty new to Qt.
    I am using Qt and the Qt plugin for Visual Studio 2010. I am creating a multi-library project that involves plugins and interfaces. While solving an earlier problem I temporarily set one of the dll projects (BuilderCore) to build a static library. I got it to build fine but I noticed I was missing one of the dlls in the Win32 Debug folder. I realized that I was still doing a static library build for that particular project. So I changed it back to the dll version.

    As soon as I changed it back I got 7 linking errors. I have tried all the "removing Q_OBJECT" as many LNK2019 and LNK2001 articles have suggested and then adding back. I have tried compiling with and without the Q_OBJECT in the derived class without success.

    Some possibly important information. The IBuilderRole "interface" class is located in the BuilderCore dll (that was originally statically linked when it worked). It is derived from QObject and a basic ground level BuilderObject class that defines all classes that need specific object information stored for use in scripting and events that will occur within the application. The BuilderClient class is derived from the IBuilderRole interface and is in its own separate dll. All functions listed have been implemented in a cpp file.

    Here is the IBuilderRole header:
    @
    namespace BuilderCore
    {

    class IBuilderRole : public QObject, BuilderObject
    {
    Q_OBJECT

    public:
    IBuilderRole(const char* derivedRoleName, int roleID);
    virtual ~IBuilderRole();
    QList<IBuilderMode*>& GetModes() const;
    QList<QAction*>& GetActions() const;
    BuilderRoles GetRole() const;

    signals:
    void RoleAdded(); // triggered when Role has been initialized
    void RoleReady(); // triggered when Role is ready to begin
    void RoleStarted(); // triggered when Role has first started
    void RoleBeginRemove(); // triggered when Role needs to end
    void RoleEndRemove(); // triggered when Role has ended
    void RoleCleared(); // triggered just before dynamic library is unloaded

    public:
    virtual void AddRole() = 0;
    virtual void SetupRole() = 0;
    virtual void Start() = 0;
    virtual void Stop() = 0;
    virtual void ShutdownRole() = 0;
    virtual void RemoveRole() = 0;

    protected:
    QList<IBuilderMode*>& mModes;
    QList<QAction*>& mActions;
    BuilderRoles mRole;
    };

    }

    Q_DECLARE_INTERFACE(BuilderCore::IBuilderRole, "BuilderRoleInterface/1.0")
    @

    Here is the BuilderClient class header. Note that I have experimented with the Q_OBJECT line with and without the comment marks. Without the comment line it it says "undefined interface" in reference to the Q_INTERFACES line. Adding the BuilderCore:: namespace in front of IBuilderRole in this line gets rid of that error but goes back to the problem with linking.
    @
    namespace BuilderCore
    {

    class BUILDERCLIENT_EXPORT BuilderClient : public IBuilderRole
    {
    //Q_OBJECT
    Q_INTERFACES(IBuilderRole)

    public:
    BuilderClient();
    ~BuilderClient();

    public:
    virtual void AddRole();
    virtual void SetupRole();
    virtual void Start();
    virtual void Stop();
    virtual void ShutdownRole();
    virtual void RemoveRole();

    private:
    // Nothing yet...
    };

    }
    @

    Here are the link errors I am getting:
    @
    3> Creating library D:\Developing\Projects\IMT\Rosweld\trunk\Source\Builder\Win32\Debug\BuilderClient.lib and object D:\Developing\Projects\IMT\Rosweld\trunk\Source\Builder\Win32\Debug\BuilderClient.exp
    3>builderclient.obj : error LNK2019: unresolved external symbol "public: __thiscall BuilderCore::IBuilderRole::IBuilderRole(char const *,int)" (??0IBuilderRole@BuilderCore@@QAE@PBDH@Z) referenced in function "public: __thiscall BuilderCore::BuilderClient::BuilderClient(void)" (??0BuilderClient@BuilderCore@@QAE@XZ)
    3>builderclient.obj : error LNK2001: unresolved external symbol "public: virtual struct QMetaObject const * __thiscall BuilderCore::IBuilderRole::metaObject(void)const " (?metaObject@IBuilderRole@BuilderCore@@UBEPBUQMetaObject@@XZ)
    3>builderclient.obj : error LNK2001: unresolved external symbol "public: virtual void * __thiscall BuilderCore::IBuilderRole::qt_metacast(char const *)" (?qt_metacast@IBuilderRole@BuilderCore@@UAEPAXPBD@Z)
    3>builderclient.obj : error LNK2001: unresolved external symbol "public: virtual int __thiscall BuilderCore::IBuilderRole::qt_metacall(enum QMetaObject::Call,int,void * *)" (?qt_metacall@IBuilderRole@BuilderCore@@UAEHW4Call@QMetaObject@@HPAPAX@Z)
    3>builderclient.obj : error LNK2019: unresolved external symbol "public: virtual __thiscall BuilderCore::IBuilderRole::~IBuilderRole(void)" (??1IBuilderRole@BuilderCore@@UAE@XZ) referenced in function "public: virtual __thiscall BuilderCore::BuilderClient::~BuilderClient(void)" (??1BuilderClient@BuilderCore@@UAE@XZ)
    3>builderclient.obj : error LNK2019: unresolved external symbol "public: void __thiscall BuilderCore::IBuilderRole::RoleAdded(void)" (?RoleAdded@IBuilderRole@BuilderCore@@QAEXXZ) referenced in function "public: virtual void __thiscall BuilderCore::BuilderClient::AddRole(void)" (?AddRole@BuilderClient@BuilderCore@@UAEXXZ)
    3>D:\Developing\Projects\IMT\Rosweld\trunk\Source\Builder\Win32\Debug\BuilderClient.dll : fatal error LNK1120: 6 unresolved externals
    @

    The only thing I can think of (but I don't know how to do) is that perhaps the moc files for the BuilderCore class would be needed for the derived builderclient class as well?



  • UMMM... DUH... I cannot believe I overlooked the missing Export tag... I only noticed it after posting this and looking at the two together. Anyway... this is the only post I have found on the internet that talks about this kind of problem occuring only after switching from static to dynamic so I guess I will just leave it up. Maybe someone else will benefit from this ridiculous error on my part.

    So here is the solution: I forgot to declare the class an export by using the QT define generated when the project first gets made. The class line of the first file (Interface) should read:

    class BUILDERCORE_EXPORT IBuilderMode : QObject, BuilderObject



  • How do I mark this as answered?



  • Hi primem0ver.
    Thank you for sharing solution.
    You can edit first post and prepend [Solved] to caption.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.