PDA

View Full Version : how to use Qt Library that has slots/signals in a non Qt Application ?



NeroViper
26th June 2015, 04:56
Hi
I have written a simple SSL Server and Client that i require for my moba project (using the echo server examples of Qt5).
Testing it them both out in the localhost everything worked fine.

Since we are using Unreal Engine 4 to built our game my next step was to integrate the code (or use it as a external library) into unreal.
After a a few hours of testing i got around making Qt work with Unreal but i found out that Signals/Slots are not working.

1)After some search i found that QCoreApplication or QApplication for UI apps needs to run for signals to work.
2)To make it work i would have to recompile Unreal Engine with qt... which is near impossible given Unreal's own custom compile systems.

The problem is i both do not know how to implement this in a Qt Library and that just writing QCoreApplication::exec(); in the Unreal Engine 4 project code
does nothing. (The server does return that it is listening though if probed with .isListening())

To avoid confusion i will make a simple c++ project (non qt) and try to import the qt server library.

What i need is someone to explain to me how i would go about having my server listen to signals normally
(that will be a library), Server.lib Server.h Server.dll etc.
while the main project/app will not be using qt (or at least not compiling with it, in other words not mocking).

anda_skoa
26th June 2015, 09:25
You don't need an event loop for signal/slots to work within the same thread.
That is only needed for cross-thread signal/slots connections (Qt::QueuedConnection).

My guess is that you are using the socket with it asynchronous API and need the eventloop for that.

You'll need your application's code to call some function in you library that behaves similar to what main() would do in a Qt application, i.e. create a QCoreApplication object and calling exec() on it.

Cheers,
_

NeroViper
26th June 2015, 11:05
You don't need an event loop for signal/slots to work within the same thread.
That is only needed for cross-thread signal/slots connections (Qt::QueuedConnection).

My guess is that you are using the socket with it asynchronous API and need the eventloop for that.

You'll need your application's code to call some function in you library that behaves similar to what main() would do in a Qt application, i.e. create a QCoreApplication object and calling exec() on it.

Cheers,
_

If understand this correctly then given my code structure
Within Server.h (My class with slots for the server)
I should create something like

void DLLMain(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
a.exec();
}

And this should be enough?

anda_skoa
26th June 2015, 11:24
Well, in between those two lines you might want to create whatever class you have that is the "top" of your qt code.

Cheers,
_

yeye_olive
26th June 2015, 11:35
Let's see...

You have a main application with its own (non-Qt) event loop, and a library that uses Qt's asynchronous socket API and thus needs a Qt event loop. I can think of several approaches.

You could rewrite your library in a synchronous style, so that it does not need an event loop to run.

You could integrate the two event loops. For instance, Qt can manage both event loops with a QAbstractEventDispatcher that picks up your main application's events.

You could allocate a QCoreApplication but not call QCoreApplication::exec(), and have the main application's event loop call QCoreApplication::processEvents() from time to time to let the library process its events. I recommend trying this solution first.

You could run the main application and the library in separate threads, each with its own event loop. To be honest I do not know enough details to guarantee that this can work, or even if such details are specified. Here is what I would try: from your main application, start a native thread (preferably not a QThread) for the library, in which you allocate a QCoreApplication, then the various objects that do the actual work, then call QCoreApplication::exec(). The main application can send requests to the library by some sort of asynchronous invocation of the worker objects, e.g. with QCoreApplication::postEvent(), or QMetaObject::invokeMethod(), or even cross-thread signal/slot connections (although I am not positive this would work in that particular setup). In the opposite direction, just have the library use your main application's favorite method to deliver asynchronous notifications.

NeroViper
26th June 2015, 12:15
Thank you for you info.

For a bit more detail this Server will be the master server basically if there 1000 game sessions given our games structure
that means 2000 clients could possibly prob it for information at any time.

This server will hold all the critical client account info login, in game currency etc...

The client is pretty similar in structure and is only there to request its data after a successfull login

Finally (completely unrelated to the subject just for clearance)
A seperate dedicated server written inside Unreal Engine 4 will be used for all the ingame real time playthrough and
will act as a client at the end of game session to update the clients info.

I will keep in touch with my progress and report back here for anyone that might ever be interested. thanks again!

NeroViper
29th June 2015, 10:11
Success!!!
Using the seperate non qt thread suggestion i was able to make the server run as part of the Unreal Engine 4
its responding from any app with my client side NICE!

Thanks again yeye_olive and anda_skoa for your advice!

Now to find out how the hell i am gonna get Unreal to know when i receive data... (communicate between threads)

If Someone wants to know about the implementation works please make a post here requesting it because my time is very limited
and i would avoid making a tut if i could :p (sorry)... if at least one wants it though i will be the good Samaritan.

Cheer, NeroViper.

Alkaline
18th August 2015, 13:27
NeroViper, could you describe your successful attempt?

I have similiar problem: I implemented simple QLocalServer in my library, which i need to run from non-Qt daemon. I tried to act like http://stackoverflow.com/questions/2150488/using-a-qt-based-dll-in-a-non-qt-application, but my server behaviour is unstable: it accepts incoming connections, can send few bytes to connected client, then sending slots stops reacting on emitted signals. Very strange fact is that server slots, reacting on client disconnected event still works.

Can you post piece of your successfull code here?

Thanks