In order to test some functions of a Qt application (named qtapp), I build the Qt application as lib/dll library. The ctor and dtor have been correctly exported in the library. However compiling the test project (a Qt console project named consoleTest) is always running to the following link errors:
Link:
1> Bibliothek "C:\Users\gmbh\test\x64\Debug\consoleTest.lib" und Objekt C:\Users\gmbh\test\x64\Debug\consoleTest.exp" werden erstellt.
1>moc_testFour.obj : error LNK2001: Nicht aufgelöstes externes Symbol ""public: static struct QMetaObject const qtapp::staticMetaObject" (?staticMetaObject#qtapp##2UQMetaObject##B)".
1>testFour.obj : error LNK2001: Nicht aufgelöstes externes Symbol ""public: static struct QMetaObject const qtapp::staticMetaObject" (?staticMetaObject#qtapp##2UQMetaObject##B)".
1>C:\Users\gmbh\test\x64\Debug\consoleTest.exe : fatal error LNK1120: 1 nicht aufgelöste Externe
The Qt application is quite simple:
#ifndef QTAPP_H
#define QTAPP_H
#include <QtWidgets/QMainWindow>
#include "ui_qtapp.h"
class __declspec(dllexport) qtapp : public QMainWindow
{
Q_OBJECT
public:
qtapp(QWidget* parent = 0);
~qtapp();
private:
Ui::qtappClass ui;
};
#endif // QTAPP_H
Implementation:
#include "qtapp.h"
__declspec(dllexport) qtapp::qtapp(QWidget* parent)
: QMainWindow(parent)
{
ui.setupUi(this);
}
__declspec(dllexport) qtapp::~qtapp()
{
}
If I simply include #include "qtapp.h" in the test project, the compiler yields the above error.
My questions:
What are the causes for the errors?
How to correctly deploy a Qt
application as lib?
My compiler is visual studio 2013, qt has the version of 5.4.2
That's actually a question independent of Qt. When linking an application against the library you need to have __declspec(dllimport) instead of __declspec(dllexport).
To achieve that, one usually uses defines that change when linking the library vs linking the application against the library. Microsoft has a help page on that "Importing into an Application Using __declspec(dllimport)".
The Qt documentation provides another one. The one thing where Qt can help, is replacing the __declspec by a cross-platform Q_DECL_IMPORT.
Related
This is my first time using QMap and I don't know what I'm doing wrong.
#include <QMap>
QMap<QString, int> name_sec_age;
name_sec_age.insert("willy", 593381460);
my errors are:
"unknown type name 'name_sec_age'"
and "expected unqualified id"
I'm using Qt Creator 4.0 with Qt 5.6 on a mac.
Side note: the run button on Qt Creator isn't available. To run my app I build it and then open the app from its path in finder. rather annoying.
You can't run code in the wild like that, it needs to be in a function.
#include <QMap>
#include <QString>
#include <QDebug>
int main() {
QMap<QString, int> name_sec_age;
name_sec_age.insert("willy", 593381460);
qDebug() << name_sec_age;
}
Your setup must be messed up somehow. Perhaps you'll have more luck by installing macports and using Qt/Qt Creator from there.
The following compiles just fine for me under Qt 5.5.1:
#include <QMap>
int main() {
QMap<QString, int> name_sec_age;
name_sec_age.insert("willy", 593381460);
}
I have a problem subclassing a VTK class, but I think the problem could be linked to any kind of library.
I did a vtkInteractorStyleImage subclass, just overriding a method:
#ifndef dcmInteractorStyleImage_h
#define dcmInteractorStyleImage_h
#include "vtkInteractionStyleModule.h" // For export macro
#include "vtkInteractorStyleImage.h"
class VTKINTERACTIONSTYLE_EXPORT dcmInteractorStyle : public vtkInteractorStyleImage
{
public:
static dcmInteractorStyle *New();
vtkTypeMacro(dcmInteractorStyle, vtkInteractorStyleImage);
virtual void OnLeftButtonDown();
void PrintSelf(ostream& os, vtkIndent indent);
};
#endif
The thing is I use it in a Qt class. So I include this in my CMakeLists.txt (simplified):
set(GENERIC_VIEW_CPP
View/UI/dcminteractorstyle.cpp # my new class
)
SET(GENERIC_VIEW_H
View/UI/dcminteractorstyle.h # my new class
)
add_library(generic ${GENERIC_VIEW_CPP} ${GENERIC_VIEW_H})
...
add_library(ui_qt ${UI_QT_CXX}
${UI_FORM_HEADERS} ${UI_RESOURCES_RCC}
${MODEL_WRAPPED_HEADERS}
${GENERIC_VIEW_CPP} ${GENERIC_VIEW_H} #necesary here?
)
qt5_use_modules(ui_qt Core Gui Widgets)
----------------------------------------------------------
# VTK
find_package(VTK REQUIRED)
include(${VTK_USE_FILE})
# ITK
find_package(ITK REQUIRED)
include(${ITK_USE_FILE})
if (ITKVtkGlue_LOADED)
find_package(VTK REQUIRED)
include(${VTK_USE_FILE})
else()
find_package(ItkVtkGlue REQUIRED)
include(${ItkVtkGlue_USE_FILE})
set(Glue ItkVtkGlue)
endif()
------------------------------------------------
set_source_files_properties(${UI_RESOURCES_RCC} PROPERTIES GENERATED ON)
add_executable(UtilidadDICOM WIN32 main.cpp ${UI_RESOURCES_RCC})
target_link_libraries(UtilidadDICOM
model
ui_qt
generic
${Glue}
${VTK_LIBRARIES}
${ITK_LIBRARIES}
)
The error trying to compile:
ui_qt.lib(viewerwidget.cpp.obj):-1: error: LNK2019: unresolved
external symbol "public: static class dcmInteractorStyle * __cdecl
dcmInteractorStyle::New(void)" (?New#dcmInteractorStyle##SAPAV1#XZ)
referenced in function "public: static class vtkSmartPointer __cdecl vtkSmartPointer::New(void)"
(?New#?$vtkSmartPointer#VdcmInteractorStyle####SA?AV1#XZ)
ui_qt is a library declared in CMake, as you can see above.
Any ideas? Thank you.
Short answer is that your class is not being linked. Try seeing the value in generic just before linking it to your executable. Do a message just before target_link_libraries:
MESSAGE(${generic})
and see if the generic.lib is actually being linked.
I am trying to connect to SQL Server 2008R2 with my qt application in windows but I am getting errors. Here's what I am doing:
#include "ui_test1.h";
#include "QtSql/QtSql";
void Test1::on_btnsnd_clicked()
{
QSqlDatabase db = QSqlDatabase::addDatabase("ODBC");
db.setHostName("ITPL_PC1");
db.setDatabaseName("Test");
db.setUserName("sa");
db.setPassword("insforia");
db.open();
QSqlQueryModel *model = new QSqlQueryModel;
QString query = "insert into qttable(PID) values('ARUP')";
model->setQuery(query, db);
db.close();
}
i am getting this error 27 times :
test1.obj:-1: error: LNK2019: unresolved external symbol "__declspec(dllimport) public: __thiscall QSqlDatabase::~QSqlDatabase(void)" (__imp_??1QSqlDatabase##QAE#XZ) referenced in function "private: void __thiscall Test1::on_btnsnd_clicked(void)" (?on_btnsnd_clicked#Test1##AAEXXZ)
I don't know how to do this (I found this in google.)
What should I do to fix it?
If you use MSVC, you should add %QTDIR%/lib/QtSql4.lib to Release configuration of your project and %QTDIR%/lib/QtSqld4.lib to Debug one. You should change 4 in file names to 500, if you use Qt 5.0. So, file names would be %QTDIR%/lib/QtSql500.lib and %QTDIR%/lib/QtSqld500.lib
If you use QtCreator you should add the next line into your .pro file
QT += sql
Upd: added description for QtCreator's .pro file
I've got a relatively simple Qt 5.0 project that uses CMake 2.8.9:
CMakeLists.txt:
cmake_minimum_required(VERSION 2.8.9)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
project(hello-world)
find_package(Qt5Widgets REQUIRED)
qt5_wrap_ui(hello-world_UI MainWindow.ui)
add_executable(hello-world MainWindow.cpp main.cpp ${hello-world_UI})
qt5_use_modules(hello-world Widgets)
MainWindow.h:
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow();
virtual ~MainWindow();
private:
Ui::MainWindow * const ui;
};
#endif // CMAINWINDOW_H
MainWindow.cpp:
#include "MainWindow.h"
#include "ui_MainWindow.h"
MainWindow::MainWindow()
: ui(new Ui::MainWindow)
{
}
MainWindow::~MainWindow()
{
delete ui;
}
main.cpp:
#include <QApplication>
#include "MainWindow.h"
int main(int argc, char * argv[])
{
QApplication app(argc, argv);
MainWindow win;
win.show();
return app.exec();
}
The project also includes a .ui file created with Qt Creator 2.6.1 (MainWindow.ui).
When I attempt to build the file with g++ on Linux, I receive the following errors:
CMakeFiles/hello-world.dir/MainWindow.cpp.o: In function `MainWindow::MainWindow()':
MainWindow.cpp:(.text+0x3b): undefined reference to `vtable for MainWindow'
MainWindow.cpp:(.text+0x4d): undefined reference to `vtable for MainWindow'
CMakeFiles/hello-world.dir/MainWindow.cpp.o: In function `MainWindow::~MainWindow()':
MainWindow.cpp:(.text+0xaf): undefined reference to `vtable for MainWindow'
MainWindow.cpp:(.text+0xc1): undefined reference to `vtable for MainWindow'
collect2: error: ld returned 1 exit status
What could possibly be causing this sort of error? I recently switched to CMake from qmake and I never remember running into this much trouble getting a trivial example to compile. What am I doing wrong?
Edit: here is the command being used to link everything:
/usr/bin/c++ CMakeFiles/hello-world.dir/MainWindow.cpp.o
CMakeFiles/hello-world.dir/main.cpp.o -o hello-world -rdynamic
/usr/local/Qt-5.0.0/lib/libQt5Widgets.so.5.0.0
/usr/local/Qt-5.0.0/lib/libQt5Gui.so.5.0.0
/usr/local/Qt-5.0.0/lib/libQt5Core.so.5.0.0
-Wl,-rpath,/usr/local/Qt-5.0.0/lib
Turns out I forgot:
set(CMAKE_AUTOMOC ON)
At the top of the CMakeLists.txt file.
I struggled with this for a long time using all the hints published here:
http://doc.qt.io/qt-5/cmake-manual.html
And here
https://www.kdab.com/using-cmake-with-qt-5/
What I had to do was specify things in the right order. For example, the following is the top of my CMakeLists.txt. Note that the two CMAKE set directives come before add_executable. Once I did this, I was able to link without undefined symbols and vtable references. I just thought I'd post this for the benefit of others.
cmake_minimum_required (VERSION 2.8)
set (CMAKE_AUTOMOC ON)
set (CMAKE_INCLUDE_CURRENT_DIR ON)
add_executable(FHSpectrumSensor wideband_seq_spectrum_sensor.cpp sensor.cpp gui.cpp ${gui_SRC})
Later in the CMakeLists.txt I have the following:
find_package(Qt5Widgets REQUIRED)
find_package(Qt5Charts REQUIRED)
find_package(Qt5Core REQUIRED)
qt5_use_modules(FHSpectrumSensor Widgets Charts)
qt5_wrap_cpp(gui_SRC gui.h gui.cpp)
That did the trick.
I also ran into this problem yesterday and the above mentioned answers did't help. I already used set (CMAKE_AUTOMOC ON) and also qt5_wrap_cpp.
I tried to remember what I did, because I had a working version but it stopped working after "some" changes. I finally remembered that I tried to split the include files into a separate directory hierarchy. After reverting that and putting the include files back into the CMakeLists.txt it worked again. I sure don't know why, and I would like to know what went wrong, but I settled now for keeping the includes near the cpp files.
set(SOURCES
buffer.h
ITVSet.h
MainWindow.h
MainWindow.cpp
TVSet.h
TVSet.cpp
)
I created a new 'C++ library' project in Qt, which has the following header file:
#include "Test_global.h"
#include <QString>
#include <QTcpServer>
class TESTSHARED_EXPORT Test : QTcpServer
{
Q_OJECT
public:
Test();
~Test();
signals:
void NewMessage(QString);
};
(The implementation file is basically empty.)
When I try to build the object, I get errors:
Test.h:8: error: ISO C++ forbids declaration of ‘Q_OJECT’ with no type
Test.h:10: error: expected ‘;’ before ‘public’
Test.cpp:3: error: definition of implicitly-declared 'Test::Test()'
So it looks like moc isn't processing the file at all. What have I done wrong?
It should be Q_OBJECT, not Q_OJECT.