PDA

View Full Version : Linking problem, QMetaObject error: two simple libraries and VS2013.



Paradox
20th November 2015, 12:21
Hi

I have some annoying troubles linking two libraries under Windows VS2013 and Qt 5.3.1 (Windows 7). Solutions for two library are generated from CMake.

I have a library A, the stub compiled is like this one:

#ifndef __A
#define __A

#include <QThread>
#include <QtGui/QKeyEvent>
#include <QtOpenGL/QGLWidget>
#include <QtDesigner/QDesignerExportWidget>

#include "ExportSymbols.h"

class LIBRARY_EXPORT A : public QGLWidget
{
Q_OBJECT

public:
A(QWidget* p_Parent = 0, const QGLWidget* p_ShareWidget = 0, Qt::WindowFlags p_WindowFlags = 0);

~A();

void enableRenderThread();

void paintGL();

void update(double time);

virtual void resizeGL(int p_Width, int p_Height);

virtual void keyPressEvent(QKeyEvent* p_Event);

virtual void keyReleaseEvent(QKeyEvent* p_Event);

virtual void mousePressEvent(QMouseEvent* p_Event);

virtual void mouseReleaseEvent(QMouseEvent* p_Event);

virtual void mouseMoveEvent(QMouseEvent* p_Event);

signals:
void render_SG();
};

#endif //__A

//IMPLEMENTATION

#include "A.h"

A::A(QWidget* p_Parent, const QGLWidget* p_ShareWidget, Qt::WindowFlags p_WindowFlags) :
QGLWidget(QGLFormat(QGL::DoubleBuffer | QGL::DepthBuffer | QGL::Rgba | QGL::StencilBuffer | QGL::AlphaChannel | QGL::StereoBuffers), p_Parent, p_ShareWidget, p_WindowFlags)
{

}

A::~A() {
}

void A::enableRenderThread() {
connect(this, SIGNAL(render_SG()), this, SLOT(update()));
}

void A::paintGL() {
}

void A::update(double time) {
emit render_SG();
}

void A::resizeGL(int p_Width, int p_Height)
{

}

void A::keyPressEvent(QKeyEvent* p_Event)
{

}

void A::keyReleaseEvent(QKeyEvent* p_Event)
{

}

void A::mousePressEvent(QMouseEvent* p_Event)
{

}

void A::mouseReleaseEvent(QMouseEvent* p_Event)
{

}

void A::mouseMoveEvent(QMouseEvent* p_Event)
{

}

And library B:

#ifndef __B
#define __B

#include <QThread>
#include <ExportSymbols.h>

class A;
class QApplication;

class LIBRARY_EXPORT B : public QThread
{
Q_OBJECT
private:
virtual void run ();
static int m_argc;
static char** m_argv;
A* m_A;
QApplication* m_QApplication;

public:
void setA (A* a);
A* getA ();
void createWidget();

B();

virtual ~B();

static int defaultMain(int argc, char **argv, char **env);

protected:
bool createSomeWhat();
};

#endif

//IMPLEMENTATION

#include "B.h"
#include "A.h"
#include <QtWidgets/QApplication>

B::B() {
}

B::~B() {
}

bool B::createSomeWhat() {
return true;
}

int B::defaultMain(int argc, char** argv, char** env) {
QApplication::setAttribute(Qt::AA_X11InitThreads);
QApplication l_QApplication(argc, argv);
l_QApplication.connect(&l_QApplication, SIGNAL(lastWindowClosed()), &l_QApplication, SLOT(quit()));

B l_B;
l_B.start();

int l_ReturnCode = l_QApplication.exec();

return l_ReturnCode;
}

void B::setA(A* viewer) {
m_A = viewer;
}

A* B::getA() {
return m_A;
}

void B::createWidget() {
if (m_A == NULL) {
m_A = new A();
m_A->showFullScreen();
}
}

void B::run () {
createWidget();
m_A->enableRenderThread();
while (1) {
m_A->update(0);
usleep(10000);
}
}

B link A. Compilation works fine for A and B, but at link time of B I receive this error:

Error 16 error LNK2019: unresolved external symbol "public: static struct QMetaObject const A::staticMetaObject"
(?staticMetaObject@A@@2UQMetaObject@@B) referenced in function "public: static class QString __cdecl A::tr(char const *,char const *,int)"
(?tr@A@@SA?AVQString@@PEBD0H@Z)

All Qt libraries are linked inside Linker input on VS2013. Under Linux all works fine. As you see, I have Q_OBJECT all over and LIBRARY_EXPORT macro is defined like this:

#ifdef WIN32
#ifdef COMPILE_LIBRARY //TO DEFINE IN LIBRARY SOLUTION PREPROCESSOR DEFINITIONS / **UNDEFINED** (TO USE THE dllimport) FOR APPLICATIONS WHICH USES THE LIBRARY.
#define LIBRARY_EXPORT __declspec(dllexport)
#else
#define LIBRARY_EXPORT __declspec(dllimport)
#endif
#else
#define LIBRARY_EXPORT
#endif

For A and B preprocessor, COMPILE_LIBRARY is defined, so I'm using __declspec(dllexport).

Can you suggest to me some try?

Best Regards, Dario.