Qt #define "signals" clashes with GStreamer (gst) - c++

Qt, which seems to name everything else with an initial Q, does this: #define signals signals in qobjectdefs.h.
However, GStream, not naturally, does not imagine signals to be a reserved word and does this
struct _GDBusInterfaceInfo
{
/*< public >*/
volatile gint ref_count;
gchar *name;
GDBusMethodInfo **methods;
GDBusSignalInfo **signals; <==================
GDBusPropertyInfo **properties;
GDBusAnnotationInfo **annotations;
};
in gdbusintrospection.h.
Am I just to assume that Qt and GStreamer don't play well together., or is there a way around this?
Note: Qt can be persuaded to #define signals signals if I don't #define Q_MOC_RUN. But that leads to problems with classes which are using
class
{
public:
// stuff
signals:
// stuff
private:
// stuff
};
As you might have guessed by now, I am trying to take over code from someone who is not around to support it and Google is not my friend:-(
[Update] Thanks, #IpApp fro the tip (which is not working, alas).
I have been given someone else's code. Apparently it build for target, but has never been built for unit test and I have to do that (why he mix & matched, I do not know).
When I use QT_NO_KEYWORDS in Eclipse CDT, I get errors because the class definition code does not use Q_SINGAL(S) - it uses the signals macro (which is now defined as signals) to define certain public members.
I am not allowed to alter the subsytsem code, just to mock its interfaces, but I am loathe to mock all of Qt & Glib, because of the effort.
Perhaps there is a way to use libraries for one or the other, rather than including their directories into the source path?

Just follow this documentation in your qmake project file:
CONFIG += no_keywords
If you are using something else than qmake, make sure that you define the following in your buildsystem:
QT_NO_KEYWORDS
Then, you need to make sure that you use Q_SIGNALS or Q_SIGNAL all over the place in your headers so that moc (meta object compiler) is still notified that it is a signal.

I have found another solution which as for me is more convenient and simple - you should include glib headers before Qt headers, and thats all. As glib code goes before, it is unaffected by Qt define statements.

Related

What to do with .h file generated using .ui file?

I used QT Desginer to create a finalversion_with_buttons.ui file,
later i converted it to finalversion_with_buttons.h file using the command
uic -o finalversion_with_buttons.h finalversion_with_buttons.ui
in command prompt.
I got to know that we cannot have a .cpp file and .h file contains everything we need, now how do i execute/run this .h file ?
Please check Qt Creator documentation e.g. "Creating a Qt Widget Based Application". It will give you some overview how to setup qmake/CMake project based on UI form files (aka Qt Widgets). The UI files itself may not be used standalone. It is only UI description.
It is always of benefit to create a ".pro" or ".cmake" file that contails all the stuff for the compilation of the project that has several benefits, even for
small programms.
I highly suggest reading through this sites, that helped me a lot in creating/compiling projects:
https://www.cprogramming.com/tutorial/makefiles.html
https://www.cprogramming.com/tutorial/makefiles_continued.html
This is what an automatic generated .pro file of the qt creator contains and I guess self explainatory:
QT += core gui multimedia multimediawidgets
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
CONFIG += c++11
# 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 \
mainwindow.cpp
HEADERS += \
mainwindow.h
FORMS += \
mainwindow.ui
# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target
RESOURCES += \
mainwindow.qrc
If you are working with the qt designer part of the qt creator you got this xml .ui file and the easiest way to compile it would be just clicking on Build->Run or ctrl+R. If your .pro file looks like the above example with the right file names you should be good to go.
Actually it is possible to have just a c++ file and no header files - thats invented to make the projects more modular with classes - thats what c++ is all about compared with c. To quote Bjarne "Classes use to hide the ugly stuff" ..so you can read the programm and understand it without even knowing what the class files contain and do with your code with a proper reference, and you don't should have to care. And thats what qt does - hiding the ugly stuff you would have to do all by yourself in its classes so you can just call QPushButton and it works. (and many more benefits but to keep it simple, qt is just c++ classes)
This is an example for a class in the code without a header file:
[//example from here https://www.cprogramming.com/tutorial/lesson12.html][1]
#include <iostream>
using namespace std;
class Computer // Standard way of defining the class
{
public:
// This means that all of the functions below this(and any variables)
// are accessible to the rest of the program.
// NOTE: That is a colon, NOT a semicolon...
Computer();
// Constructor
~Computer();
// Destructor
void setspeed ( int p );
int readspeed();
protected:
// This means that all the variables under this, until a new type of
// restriction is placed, will only be accessible to other functions in the
// class. NOTE: That is a colon, NOT a semicolon...
int processorspeed;
};
// Do Not forget the trailing semi-colon
Computer::Computer()
{
//Constructors can accept arguments, but this one does not
processorspeed = 0;
}
Computer::~Computer()
{
//Destructors do not accept arguments
}
void Computer::setspeed ( int p )
{
// To define a function outside put the name of the class
// after the return type and then two colons, and then the name
// of the function.
processorspeed = p;
}
int Computer::readspeed()
{
// The two colons simply tell the compiler that the function is part
// of the class
return processorspeed;
}
int main()
{
Computer compute;
// To create an 'instance' of the class, simply treat it like you would
// a structure. (An instance is simply when you create an actual object
// from the class, as opposed to having the definition of the class)
compute.setspeed ( 100 );
// To call functions in the class, you put the name of the instance,
// a period, and then the function name.
cout<< compute.readspeed();
// See above note.
}
And a compiler doesn't see something else after the linker is done than that.
so
"I got to know that we cannot have a .cpp file and .h file contains
everything we need"
is not right because you can as seen in the example above. Just its not how c++ (or c with classes as it was called in the early days) should be used.
But to answer your question:
"how do i execute/run this .h file ?"
like said before, just use the qt creator and click on Run or crtl + R
(it is free for opensource and edu)
create a project file like exampled before and use qmake SampleProject.pro
in the command line. This will create a file by the name of “Makefile” in the project directory.
(like described here https://vitux.com/compiling-your-first-qt-program-in-ubuntu/
than issue the command make in the same directory
(also described here)
Create a make file like described in link 1 and 2.
Everything else is beyond the scope of this question like fiddling out the semantic for using gcc or g++
That being said, you can create QPushButtons and all the stuff with the qt creator or you can create push buttons just in the code without using the .ui xml - file
like described here:
https://www.bogotobogo.com/Qt/Qt5_LayoutNotUsingDesigner.php
But what all of the guys here highly suggest is: Get yourself a goot qt/c++ book or tutorial and learn the foundations about classes and qt and you gonna get to be a really good programmer in no time. I also hope deeply this post is able to clarify a lot of qt programming/compiling for you and you start to have fun and will create really nice applications :) Cheers

Qt testing when dependent on Network

I'm working on a Qt project, and I need to be able to write unit tests for functions that depend on QNetworkAccessManager.
Google Mock seems like an overkill for my purposes, and I found this answer which suggest using a "linker trick" to mock the class. However, I'm very new to C++ (and C in general), and I'm having somewhat hard time in understanding the exact way I'm supposed to use this "trick". Am I supposed to manually change the header file to run the test, or is there some nicer way to do it (I'm assuming there is).
Any kind of an example on the header/code structure to do this correctly would be an immense help.
You could use linker tricks, but as QNetworkAccessManager can be subclassed, you might find it easier just to do that.
For example, if you want to make a version that doesn't actually connect, you could do something like:
class FailQNetworkAccessManager : public QNetworkAccessManager
{
Q_OBJECT
public:
FailQNetworkAccessManager(QObject *parent = Q_NULLPTR):QNetworkAccessManager(parent){}
protected:
QNetworkReply* createRequest(Operation op, const QNetworkRequest &originalReq, QIODevice *outgoingData = Q_NULLPTR)
{
QNetworkReply* rep = QNetworkAccessManager::createRequest(op, originalReq, outgoingData);
// Queue the abort to occur from main loop
QMetaObject::invokeMethod(req, "abort", Qt::QueuedConnection);
return rep;
}
};
Then your test code can provide your class with the FailQNetworkAccessManager rather than the real one, and all requests should abort as soon as they're created. (This is just example code, I haven't actually tried this code yet - I would also recommend splitting this into header & cpp files).
You should also have a look at the Qt Test system, which is the built in test framework.

Why is a "user breakpoint" called when I run my project with imported .lib, not when code is inline?

The Situation
I am writing a wrapper library for GPIB communications for setting up specific instruments according to a clients specifications to automate some of their processes. I have to use C++ and the old '98 compiler in VC++ 6.0 running on a Windows NT machine to maintain compatibility with some other devices they use regularly.
I am trying to make a class that combines some GPIB commands into easier to remember functions, while also keeping the capability of directly communicating with the instruments. To that end, I have compiled different parts of my project into different libs and dlls, each dll being a different device that they might want to communicate with. I also made a generic dll base class from which all the specific instrument classes inherit, hopefully making the whole setup as modular as possible.
The Problem
So, with all that said, I have an issue when I try to test the different dlls/modules. I created a project to test the generic base class, added the .lib file to the project, which links to the .dll, and also #included the header file for that dll. testGeneric.cpp looks like this:
#include "GENERIC.h"
void main(void) {
GPIBInstrument hp(2); //connects to device at primary address #2
hp.write("*IDN?");
}
Super simple. To be clear, I also have the GENERIC.lib linked in the "Resource Files" folder in VC++ 6.0, and I have GENERIC.dll accessible from the path variable.
Moving on, GENERIC.h looks like this (select parts):
#ifndef GENERIC_H
#define GENERIC_H
#include <string>
#include <windows.h>
#include "decl-32.h"
#ifdef GENERIC_EXPORT
#define GENERIC_API __declspec(dllexport)
#else
#define GENERIC_API __declspec(dllimport)
#endif
...(Inline exception classes)...
class GENERIC_API GPIBInstrument {
...
public:
void write(std::string command);
...
};
#endif
Just showing the relevant methods. Then GENERIC.cpp:
#define GENERIC_EXPORT
#include "GENERIC.h"
...
void GPIBInstrument::write(std::string command) {
ibwrt (handle, &command[0u], command.length());
std::cout << command << std::endl;
if (ibsta & TIMO) {
timeoutError();
}
if (ibsta & ERR) {
error("Unable to write command to instrument: " + command);
}
}
So, looks pretty good right? No issues. Compiles fine. I try running it, and BLAM! I get this: "User breakpoint called from code at 0x77f7645c". So, then I thought, well maybe it would work if I put all the code from GENERIC.h and GENERIC.cpp into one file, and #included that file all as inline code. So I tried it, and it and it compiled nicely, and ran fine.
Question (<-AHA!... But...)
What am I doing wrong!? Something with the way I'm making the .dll? Or the .lib? Or something else entirely?
EDIT (WHY!?)
So, after a bit of debugging, I found that it was something to do with passing a string literal. So I just modified it to:
std::string command = "*IDN?";
hp.write(command);
and it worked fine. My followup question, is why? What's the difference between having a string literal passed, versus assigning that to a variable and then passing it in?
Using complex types such as std::string as a parameter at a DLL boundary is tricky. You must ensure that the exe and the DLL use the exact same instance of the library code. This requires that you build them both to use the same version of the DLL version of the runtime library.

Implementing your own property system (Qt-like)

I want to implement my own simple property system (C++) similiar to one provided by Qt's Q_PROPERTY. The problem is that Qt's properties doesn't work from inside macros which I'm trying to use to add some additional functionality above properties. The aim is to be able to declare a property and automatically get access both through properties string name representation and regular methods:
MY_PROPERTY(QString, Name)
...
getObject()->setProperty("Name", "John");
...
myObject->setName("John");
QString name = myObject->getName();
I want to add all the needed functionality with a single line but the following code will not work, since MOC doesn't expand macros:
#define MY_PROPERTY(type, name)\
Q_PROPERTY(type name READ name WRITE change##name)\
\
void set##name(type param)\
{\
m_##name = param;\
DO SOMETHING
}\
Please advice any good books/articles on this topic.
most (>95%) condition, Qt Propery System is enough, if you really want to add something on yourself property when its setting or getting, you can use Qt signal/slot System to do this.
if you finally still want to do you own Property System, I think the best reference is Qt source code, isn't it?

Including C++ headers in user mode programs built with NT DDK

So...I have a kernel mode component and a user mode component I'm putting together using the turnkey build environment of the NT DDK 7.1.0. The kernel component is all .c/.h/.rc files. The user mode component is .cpp/.c/.h/.rc files.
At first it seemed simplest to use build for both, as I saw you could modify the ./sources file of the user mode component to say something like:
TARGETNAME = MyUserModeComponent
TARGETTYPE = PROGRAM
UMTYPE = windows
UMENTRY = winmain
USE_MSVCRT = 1
That didn't seem to cause a problem and so I was pleased, until I tried to #include <string> (or <memory>, or whatever) Doesn't find that stuff:
error C1083: Cannot open include file: 'string': No such file or directory
Still, it's compiling the user mode piece with C++ language semantics. But how do I get the standard includes to work?
I don't technically need to use the DDK build tool for the user mode piece. I could make a visual studio solution. I'm a bit wary as I have bumped into other annoyances, like the fact that the DDK uses __stdcall instead of __cdecl by default... and there isn't any pragma or compiler switch to override this. You literally have to go into each declaration you care about and change it, assuming you have source to do so. :-/
I'm starting to wonder if this is just a fractal descent into "just because you CAN doesn't mean you SHOULD build user mode apps with the DDK. Here be dragons." So my question isn't just about this particular technical hurdle, but rather if I should abandon the idea of building a C++ user mode component with the DDK tools...just because the kernel component is pure C.
To build a user mode program with WINDDK you need to add some variables to your SOURCES file:
386_STDCALL=0 to use cdecl calling convention by default
USE_STL=1 to use STL
USE_NATIVE_EH=1 to add a support for exception handling
Everything else you already have.
I'll put my full SOURCES file for reference:
TARGETNAME = MyUserModeComponent
TARGETTYPE = PROGRAM
TARGETPATH = obj
UMTYPE = console
UMENTRY = main
USE_MSVCRT = 1
USE_NATIVE_EH=1
USE_STL=1
386_STDCALL=0
SOURCES= main.cpp
And main.cpp:
#include <iostream>
#include <string>
using namespace std;
int main()
{
string s = "bla bla bla!";
cout << s;
return 0;
}
Have fun!
Quick Answer
Abandon the idea of building user-mode components with DDK tools (although I find the concept fascinating :-P)
Your kernel mode component should be built separately from the user mode components as a matter of good practice.
Vague thoughts
Off the top of my head, and this really speaking from limited experience...there are a lot of subtle differences that can creep up if you try to mix the two together.
Using your own example of __cdecl vs __stdcall; You have two different calling conventions. _cdecl is all kernel stuff and all of the C++ methods are wrapped around in WINAPI (_stdcall) passing conventions and __stdcall will clean do auto stack clean up and expect frame pointers inserted all over the place. And if you by accident use compiler options to trigger a __fastcall, it would be a pain to debug.
You can definitely hack something together, but do you really want to keep track of that in your user-space code and build environment? UGH I say.
Unless you have very specific engineering reasons to mix the two environments, (and no a unified build experience is not a valid reason, because you can get that from a batch file called buildall.bat) I say use the separate toolchains.