View Full Version : QProcess and none-string arguments
Raistlin
11th March 2008, 17:17
I need to combine some code I have written myself.
The main program is written in LabVIEW and has C-style DLLs calls, where the DLLs contain C++ code with Qt.
The second part is written entirely in Qt.
I tried to integrate the second part in my LabVIEW code, but this is not trivial because of the threads, signals/slots, event handling, ... Therefore, I postponed this to later and would now like to use QProcess as a solution.
I need to pass a lot of parameters from the main program to the second application. These range from strings to ints, floats, doubles, ... I thought I could use the 'arguments' of void QProcess::start( const QString & program, const QStringList & arguments) . I am not sure how to handle this however.
Format all parameters into QStrings and append them to the QStringList.
Construct a QDataStream based on a QByteArray, serialize all date in there, and construct a QString based on this. I suppose however that I can run into troubles because of '0' bytes, and have to use QT_NO_CAST_FROM_ASCII to avoid strange things happening to the data.
Or is there a more elegant way? Any suggestions?
wysota
11th March 2008, 20:52
I suggest you format the data as XML and pass it to stdin of the other application (so not as a parameter but as a stream of data).
Raistlin
12th March 2008, 10:23
Thank you for the suggestion.
I do however still have some issues to get the inter process communication to work. This is how I handle it. The application is launched succesfully, but it does not seem to receive any data. I use a QFile constructed with stdin in my server to capture the input from the startserver program.
The main.cpp of my startserver program:
#include <QCoreApplication>
#include "startserver.h"
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
Startserver w;
return a.exec();
}
The startserver class:
#include <QDir>
#include <QFile>
#include <QProcess>
#include <QString>
#include <QStringList>
class Startserver : public QObject
{
Q_OBJECT
public:
Startserver(QObject *parent = 0);
~Startserver();
private slots:
void serverFinished(int, QProcess::ExitStatus);
private:
QProcess* process_;
};
Startserver::Startserver(QObject* parent) : QObject(parent)
{
QString appName = QString("myapplication.exe");
process_ = new QProcess(this);
process_->start(appName);
process_->waitForStarted();
connect(process_, SIGNAL(finished(int, QProcess::ExitStatus)), this, SLOT(serverFinished(int, QProcess::ExitStatus)));
//Start a timer, which sends data to the server each second
QTimer* timer = new QTimer(this);
timer->setInterval(1000);
connect(timer, SIGNAL(timeout()), this, SLOT(sendData()));
timer->start();
}
Startserver::~Startserver()
{
}
void Startserver::serverFinished(int exitCode, QProcess::ExitStatus exitStatus)
{
exit(exitCode);;
}
void Startserver::sendData()
{
//Send some data to server
//This slot is effictively called each second !!
QByteArray block;
QDataStream out(&block, QIODevice::WriteOnly);
out.setVersion(QDataStream::Qt_4_3);
out << (quint32)0;
out << QString("Hello server");
out.device()->seek(0);
out << (quint32)(block.size() - sizeof(quint32));
//Data is sent to stream each time, since bytesToWrite returns same amount each time
process_->write(block);
while (process_->bytesToWrite() > 0)
{
if (!process_->waitForBytesWritten())
break;
}
}
And here is what happens in the main class of my server program. The code is a lot bigger, so I only show what I think to be the relevant parts.
#include <QByteArray>
#include <QList>
#include <QtNetwork>
#include <QtCore>
#include <QMessageBox>
#include "ConnectionThread.h"
class OctoServer : public QTcpServer
{
Q_OBJECT
public:
OctoServer(QObject *parent = 0);
~OctoServer();
signals:
//...
public slots:
void readInput();
//...
private:
QString* directory_;
};
OctoServer::OctoServer(QObject* parent) : QTcpServer(parent)
{
QFile* stdinFile = new QFile(this);
directory_ = new QString();
//Open a file pointing to the stdin and connect incoming data signal to custom slot
stdinFile->open(stdin, QIODevice::ReadOnly);
connect(stdinFile, SIGNAL(readyRead()), this, SLOT(readInput()));
//...
}
void OctoServer::readInput()
{
//This slot is never called !!
QMessageBox::information(0, QString("Data incoming"), QString("Data")) ;
}
OctoServer::~OctoServer()
{
delete directory_;
}
wysota
12th March 2008, 10:32
Have you tried verifying each application that they actually read/write the data to respective descriptors?
Raistlin
12th March 2008, 10:39
How exactly would I accomplish this?
Raistlin
12th March 2008, 13:20
Hmm, it seems QFile does not emit readyRead() in general. So this means I will need to poll in the idle loop for this, since QSocketNotifier is also not an option on Windows.
Good to know :).
If I could only wait for the official release of Qt 4.4 and the introduction of QSharedMemory.
wysota
12th March 2008, 13:56
You can always use platform dependent solutions.
Raistlin
12th March 2008, 14:45
Well, I implemented a connection through a QTcpSocket now, and once Qt 4.4 is available (not the beta, since we have to release this code to customers) I will take a look at QLocalServer (http://doc.trolltech.com/4.4beta/qlocalserver.html) and QLocalSocket (http://doc.trolltech.com/4.4beta/qlocalsocket.html).
wysota
12th March 2008, 15:28
If both applications are GUI-based, you can use WinAPI PostMessage() call.
Powered by vBulletin® Version 4.2.5 Copyright © 2024 vBulletin Solutions Inc. All rights reserved.