Instantiating/Accessing COM API from Qt - c++

I am trying to access a COM API of an application using Qt. However when I try to instantiate the COM API object I get:
D:\dev\git\com_example\Lights.h:441: error: undefined reference to `vtable for Lights::Application'
Now I know that this is normally associated with the fact that we have declared a method but not implemented it but I am using the Lights.tlb file provided by the SDK provider for the application and the Lights.h file referred to in the error message is auto-generated by Qt.
My .pro file is:
QT += core gui webkitwidgets network widgets sql axcontainer
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
TARGET = com_example
TEMPLATE = app
TYPELIBS = $$system(dumpcpp Lights.tlb)
HEADERS += \
LightsInterface.h
SOURCES += main.cpp\
LightsInterface.cpp
The TYPELIBS bit is what converts the Lights.tlb file to Lights.h and Lights.cpp
This is all fine, the code builds but as soon as I try to create an instance of the COM API interface I get the error. The code that does this is:
#include <QWidget>
#include <QMainWindow>
#include "Lights.h"
class LightsInterface : public QMainWindow
{
Q_OBJECT
public:
explicit LightsInterface(QWidget *parent = 0);
signals:
public slots:
private:
Lights::Application app;
};
#endif // LIGHTSINTERFACE_H
Does anybody know what I am doing wrong? Are the Lights.h and Lights.cpp files not being generated correctly from the Lights.tlb file? Am I trying to instantiate the object incorrectly?
any help greatly appreciated.
thanks

Related

The program has unexpectedly finished in QT opencv

I know that this has been posted many times,but I could not find the solution from previous posts. I followed tutorial on How to setup Qt and openCV on Windows from wiki Qt.
My .pro file and mainwindows.cpp are shown below. I wanted to open image following the example. What is wrong here? Checked the opencv version and it is the same as libs included. The PATH is also correct.
The cpp file
#include "ui_mainwindow.h"
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
cv::Mat image = cv::imread("C://1.jpg", 1);
cv::namedWindow("My Image");
cv::imshow("My Image", image);
}
MainWindow::~MainWindow()
{
delete ui;
}
and
QT += core gui
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
TARGET = opencvtest
TEMPLATE = app
DEFINES += QT_DEPRECATED_WARNINGS
SOURCES += main.cpp\
mainwindow.cpp
HEADERS += mainwindow.h
FORMS += mainwindow.ui
INCLUDEPATH += C:\opencv\build\include
LIBS += C:\opencv-build\bin\libopencv_core451.dll
LIBS += C:\opencv-build\bin\libopencv_highgui451.dll
LIBS += C:\opencv-build\bin\libopencv_imgcodecs451.dll
LIBS += C:\opencv-build\bin\libopencv_imgproc451.dll
LIBS += C:\opencv-build\bin\libopencv_features2d451.dll
LIBS += C:\opencv-build\bin\libopencv_calib3d451.dll
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
private:
Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H
When program crashes like that under Qt Creator, and you have extra libraries, the very likely reason is that the extra libraries are missing from the runtime PATH.
In this case, you need to add C:\opencv-build\bin to the PATH. There are at least 3 ways to go about it.
Edit the system environment, so that the relevant directory is always in the system PATH. You need to restart Qt Creator for this change to take effect. This is not the recommended way, unless you actually want these things in there also for other purposes.
You can edit the Build environment of the project under Qt Creator Project view. There's separate configuration for each build type, so you may need to do this to them all separately, which both good and bad. It is good, because then you can have different directory for different builds (for example debug vs relase, MSVC vs MinGW builds). It's bad because it's extra hassle and makes it easier to have something wrong.
You can add it to the run environment in the Qt Creator Project view. Then it will be the same for all build types.
In this case, 3 is probably the way to go.
Qt Creator annoyingly does not display any information about which DLL is missing, it just says the program crashed. This can be solved by instead string the "Qt command prompt" for the correct toolchain from Windows Start menu (search Qt and you should find it). Then go to the built .exe directory and run the .exe. You should now get an error dialog where Windows tells you which DLL it failed to find. Then you can look where that DLL is and add it to the path and try again, until the program starts. After you know the directories using this method, you can then add them to Qt Creator as explained above.

How to Use Same Class Between Plugins and App in Qt?

I created a plugin in Qt. Plugin Class and App Class use a same class named ShareData.
This is ShareData Class:
//sharedata.h
class ShareData
{
public:
ShareData();
};
//sharedata.cpp
ShareData::ShareData()
{
}
But When I create an instance in plugin class as follows:
//plugin.pro
INCLUDEPATH += $PWD/../echowindow/
//echoplugin.h
#include "sharedata.h"
class EchoPlugin : public QObject, EchoInterface
{
Q_OBJECT
Q_PLUGIN_METADATA(IID "org.qt-project.Qt.Examples.EchoInterface" FILE "echoplugin.json")
Q_INTERFACES(EchoInterface)
public:
EchoPlugin();
ShareData* sharedata;
};
//echoplugin.cpp
EchoPlugin::EchoPlugin()
{
sharedata = new ShareData();
}
Then I run the project and I got an error :
error: undefined reference to `ShareData::ShareData()'
Add this is my class structure:
-echoplugin
-echoplugin.pro
-echopluginwindow
-echowindow.pro
-Headers
-echointerface.h
-echowindow.h
-sharedata.h
-Sources
-echowindow.cpp
-main.cpp
-sharedata.cpp
-Plugin
-plugin.pro
-Headers
-echoplugin.h
-Sources
-echoplugin.cpp
What should I do then I can use ShareData Class in Plugin EchoPlugin Class?
Plugin should be independent of main application, so you cannot use classes defined in it. Your build error is probably beacuse of shareddata.cpp is not compiled during plugin build.
If you really want use such design I would suggest creation of library for SharedData.
INCLUDEPATH only says that you can use headers of shareddata. The problem occurs on the linking stage.

Qt with WinRT C++ build issue

I want to build a modern Windows application using WinRT (Windows 10). I use Qt 5.13.1 UWP kits for Visual Studio 2017. When building a project, it displays a lot of compilation errors:
Code:
testproject.pro
QT += core gui
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
CONFIG += c++17
# The following define makes your compiler emit warnings if you use
# any Qt feature that has been marked deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the
# deprecated API in order to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS
# You can also make your code fail to compile if it uses deprecated APIs.
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
SOURCES += \
main.cpp \
testproject.cpp
HEADERS += \
testproject.h
FORMS += \
testproject.ui
LIBS += -lwindowsapp
# Default rules for deployment.
#qnx: target.path = /tmp/$${TARGET}/bin
#else: unix:!android: target.path = /opt/$${TARGET}/bin
#!isEmpty(target.path): INSTALLS += target
testproject.h
#ifndef TESTPROJECT_H
#define TESTPROJECT_H
#include <QDialog>
#include <QDebug>
#include "winrt/Windows.System.Diagnostics.h"
using namespace winrt;
using namespace Windows::System::Diagnostics;
QT_BEGIN_NAMESPACE
namespace Ui { class TestProject; }
QT_END_NAMESPACE
class TestProject : public QDialog
{
Q_OBJECT
public:
TestProject(QWidget *parent = nullptr);
~TestProject();
private:
Ui::TestProject *ui;
};
#endif // TESTPROJECT_H
testproject.cpp
#include "testproject.h"
#include "ui_testproject.h"
TestProject::TestProject(QWidget *parent)
: QDialog(parent)
, ui(new Ui::TestProject)
{
ui->setupUi(this);
init_apartment();
auto info = SystemDiagnosticInfo::GetForCurrentSystem();
auto memory = info.MemoryUsage().GetReport().TotalPhysicalSizeInBytes();
qDebug() << memory;
}
TestProject::~TestProject()
{
delete ui;
}
Without WinRT code it compiles successfully. Any ideas how to configure WinRT using Qt? What libraries are required for Qt to run WinRT code? Thanks in advance.
Try either adding #undef X64 before #include "winrt/Windows.System.Diagnostics.h" or go to your project settings, select "Configuration Properties" -> "C/C++" -> "Preprocessor", in the dropdown next to "Preprocessor Definitions" select "Edit", remove the line X64. I've no idea what this define is for, but it conflicts with the ProcessorArchitecture::X64 enum in Windows.System.0.h.
PS. This answer is just a reproduced guesswork as I can't make much sense of the errors on the screenshot. Usually copy-pasting the text from the Output panel is more informative than the Error List.

How to get the CImg library working for Qt

I'm currently learning how to use Qt. I want to try out some simple image processing applications using Qt, and since I'm already familiar with CImg I want to use that. I guess it should be possible to do so, if not mark my question for deletion or something.
My question is: how to get CImg working for Qt? CImg is a header file. Lets say its located on my desktop. I import it using Qt creator 4.1.0, by using the "add existing file..." in the rightclick menu on the header folder. Then my menu looks like this:
.
It compiles when I add #include "CImg.h", but I can't use it, even when I'm trying to type using namespace cimg_library it will tell me that cimg_library doesn't exist. I also tried just creating a header file and copying the content of the CImg.h into it but then it simply fails to compile and the Qt Creator freezes.
Edit: I managed to make the situation a bit better by adding the header location to the include code (like this: #include "C:/Users/Marci/Desktop/CImg.h" )I can now "see" CImg related stuff in the dev environment, and it won't bother me with not finding the constructor for CImg or anything like that. However when I try to compile while using anything CImg related it will give me around 20 linker errors. (Error code: LNK2019) My .pro file looks like this:
#-------------------------------------------------
#
# Project created by QtCreator 2016-11-08T17:08:58
#
#-------------------------------------------------
QT += core gui
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
TARGET = grayscale
TEMPLATE = app
SOURCES += main.cpp\
mainwindow.cpp
HEADERS += mainwindow.h \
C:/Users/Marci/Desktop/CImg.h
LIBS += -C:/Users/Marci/Desktop/ -CImg.h
FORMS += mainwindow.ui
Edit2: after implementing the changes that PeterT suggested in his comment my .pro file looks like this:
#-------------------------------------------------
#
# Project created by QtCreator 2016-11-08T17:08:58
#
#-------------------------------------------------
QT += core gui
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
TARGET = grayscale
TEMPLATE = app
SOURCES += main.cpp\
mainwindow.cpp
HEADERS += mainwindow.h \
INCLUDEPATH += C:/Users/Marci/Desktop
FORMS += mainwindow.ui
And my mainwindow.cpp (in which i'm trying to create a CImg object) looks like this:
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <CImg.h>
using namespace cimg_library;
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
CImg<unsigned char> myimage(100,200);
}
MainWindow::~MainWindow()
{
delete ui;
}
The compiler errors i get are: error: C2871: 'cimg_library': a namespace with this name does not exist
error: C2065: 'CImg': undeclared identifier
error: C2062: type 'unsigned char' unexpected
I hope this is specific enough.
After I few months I figured it out. The problem lies in the fact, that CImg uses a windows .dll file for the visualizing functions of the class cimg_display. Since Qt is platform independent it doesnt like this. However you can make it work with an interesting trick. First you need to include the header file normally, in the project file. After that, whenever you actually #include it, you need to write the following macro:
#define cimg_display 0
In my understanding this makes it work, because the C and C++ compilers simply copy the content of the included file into the source. And thanks to the macro the compiler will ignore the class thats causing trouble for us.

Qt 5.5 QOpenGLWidget link error not linking any openGL calls

I tried to build a simple OpenGL App with Qt 5.5.1, and everything is fine up until I try to use openGL native function calls like glClearColor.
The Widget actually compiles and produces a black screen, but after I try to use any openGL native function it doesn't even link, but produces the error:
glwidget.cpp:10: error: undefined reference to '_imp__glClearColor#16'
Here is the .pro file:
QT += core gui opengl
CONFIG += windows
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
TARGET = Vehicle_simulation
TEMPLATE = app
SOURCES += main.cpp\
simulation.cpp \
glwidget.cpp
HEADERS += simulation.h \
glwidget.h
FORMS += simulation.ui
I'm using Desktop Qt mingw492_32 kit.
The strange thing though is that I did not find libQtOpenGL.so in the lib folder. Is my QT installation faulty? I tried to reinstall it multiple times, but it didn't help. Where can I download that specific library?
linking it to the project would solve the problem, but I can't seem to find it anywhere.
The problem is the openGL module is missing from the QT installation, it's not that I am unable to link to it.
After I opened up an example program by chance, just to take a look at the implementation; I found that the same QOpenGLWidget has been implemented in a new example program.
After a bit of analysis I managed to figure out the problem.
QT has an internal openGL implementation and native openGL support as well. The widget I used inherited from QOpenGLWidget, but the openGL function calls (like glClearColor) tried to access native openGL implementation in Qt. which Since those were not included in my Qt build, the project would not build.
To fix this one has to either run a custom Qt core build, or use the openGL wrapper provided by Qt.
I used the Qt wrapper in the end, which was also used by the example program Cube. the class used to implement the widget (called GLWidget in my implementation) has to inherit not only from QOpenGLWidget, but also from QOpenGLFunctions. The latter part was missing from my implementation. The source code for it is the following:
glwidget.h (initial):
#ifndef GLWIDGET_H
#define GLWIDGET_H
#include <QOpenGLFunctions>
#include <QOpenGLWidget>
class GLWidget : public QOpenGLWidget
{
Q_OBJECT
public:
explicit GLWidget(QWidget *parent);
protected:
void initializeGL();
void paintGL();
void resizeGL(int w, int h);
};
#endif // GLWIDGET_H
glwidget.h (fixed):
#ifndef GLWIDGET_H
#define GLWIDGET_H
#include <QOpenGLFunctions>
#include <QOpenGLWidget>
class GLWidget : public QOpenGLWidget, protected QOpenGLFunctions
{
Q_OBJECT
public:
explicit GLWidget(QWidget *parent);
protected:
void initializeGL() Q_DECL_OVERRIDE;
void paintGL() Q_DECL_OVERRIDE;
void resizeGL(int w, int h) Q_DECL_OVERRIDE;
};
#endif // GLWIDGET_H
Be careful!
Before any gl* functions are used the function initializeOpenGLFunctions(); has to be called, otherwise a very cryptic run-time error will pop up.
i.e.:
void GLWidget::initializeGL(){
initializeOpenGLFunctions();
glClearColor(1,0,0,1);
}
Hope this will help someone else as well.