RS232-Thread Problem
Verfasst: 3. Januar 2005 19:17
Hallo Forum,
ich bastele seid einiger Zeit an einer Klasse, die selbstständig
Daten von einem COM-Port liest und zwischenspeichert. Wenn
neue Daten vorliegen, wird ein Signal erzeugt und der Anwender
der Klasse kann sich die Daten per read() holen.
Das Prinzip habe ich unten mal skizziert.
Die mainForm erzeugt sich ein CComPort-Objekt, das wiederrum
einen Thread erzeugt, der die Daten vom COM-Port liest und
innerhalb des CComPort-Objektes speichert. Der Thread sendet
dann ein Signal an mainForm, das daraufhin die Daten aus dem
CComPort-Objekt lesen kann. Soweit funktioniert auch alles.
Wenn ich die gelesenen Daten innerhalb des Slots comDataReceived() auf der Konsole ausgebe, ist alles in Ordnung.
Sobald ich die Daten innerhalb des Slots aber in einem TextEdit
ausgeben will, stürzt das Programm ab.
Alle Daten sind reine ASCII-Zeichen. Das Programm stürzt auch
dann ab, wenn man statt der gelesenen Daten innerhalb des Slots
einen simplen Teststring im TextEdit ausgibt.
Die Fehlermeldungen beim Crash sehen meistens so aus:
Error: BadPixmap (invalid Pixmap parameter) 4
Major opcode: 56
Minor opcode: 0
Resource id: 0x50038
X Error: BadRequest (invalid request code or no such operation) 1
Major opcode: 182
Minor opcode: 0
Resource id: 0x50038
rs232test: Fatal IO error: client killed
Ich habe das Ganze auch mal ohne Signal/Slot-Mechanismus mit
einem Custom-Event implementiert, führt aber exakt zum gleichen
Verhalten. Im dem vom Thread aktivierten Slot bez. EventHandler
lässt sich kein Text auf dem TextEdit ausgeben.
Woran kann das liegen???
/********************************************/
/* MainForm */
/********************************************/
class mainForm:public QWidget
{
Q_OBJECT
public:
mainForm( QWidget* parent, const char* name, WFlags fl);
public slots:
comDataReceived( long readLen);
private:
CComPort* pComPort;
QTextEdit* pTextEdit;
};
/************************************/
/* Initialisierung */
/************************************/
void mainForm::init()
{
pTextEdit = new QTextEdit( this, "textEdit");
pComPort = new CComPort( this);
connect( pComPort, SIGNAL( comInputSignal( long)), this, SLOT( comDataReceived( long)));
}
/************************************/
/* Neue Daten vom COM-Port sind da */
/************************************/
void mainForm::comDataReceived( long al_readLen)
{
char* pInBuf;
QString tempStr;
pInBuf = new char[1000];
pComPort->read( pInBuf);
tempStr.append( (const char*)pInBuf);
cout << tempStr << endl; // OK !
pTextEdit->append( tempStr); // CRASH !
}
/********************************************/
/* Klasse zur Verwaltung eines COM-Ports */
/********************************************/
class CComPort:public QObject
{
Q_OBJECT
public:
CComPort( QWidget* pParentWidget);
read( char* pInBuf);
signals:
comInputSignal( long);
private:
/************************************/
/* Thread zum Lesen des COM-Ports */
/************************************/
class CReaderThread : public QThread
{
public:
CReaderThread( CComPort* pComPort);
run();
}
};
/************************************/
/* */
/************************************/
void CComPort::read( char* pInBuf)
{
// Gelesene Daten an den Aufrufer liefern
}
/************************************/
/* Thread holt Daten vom COM-Port */
/************************************/
void CComPort::CReaderThread::run()
{
long n;
// Lese den Port
n = Anzahl der gelesenen Bytes
// Speichere die Daten in einem Buffer von CComPort
// Signalisiere, dass neue Daten da sind
emit pComPort->comInputSignal( n);
}
ich bastele seid einiger Zeit an einer Klasse, die selbstständig
Daten von einem COM-Port liest und zwischenspeichert. Wenn
neue Daten vorliegen, wird ein Signal erzeugt und der Anwender
der Klasse kann sich die Daten per read() holen.
Das Prinzip habe ich unten mal skizziert.
Die mainForm erzeugt sich ein CComPort-Objekt, das wiederrum
einen Thread erzeugt, der die Daten vom COM-Port liest und
innerhalb des CComPort-Objektes speichert. Der Thread sendet
dann ein Signal an mainForm, das daraufhin die Daten aus dem
CComPort-Objekt lesen kann. Soweit funktioniert auch alles.
Wenn ich die gelesenen Daten innerhalb des Slots comDataReceived() auf der Konsole ausgebe, ist alles in Ordnung.
Sobald ich die Daten innerhalb des Slots aber in einem TextEdit
ausgeben will, stürzt das Programm ab.
Alle Daten sind reine ASCII-Zeichen. Das Programm stürzt auch
dann ab, wenn man statt der gelesenen Daten innerhalb des Slots
einen simplen Teststring im TextEdit ausgibt.
Die Fehlermeldungen beim Crash sehen meistens so aus:
Error: BadPixmap (invalid Pixmap parameter) 4
Major opcode: 56
Minor opcode: 0
Resource id: 0x50038
X Error: BadRequest (invalid request code or no such operation) 1
Major opcode: 182
Minor opcode: 0
Resource id: 0x50038
rs232test: Fatal IO error: client killed
Ich habe das Ganze auch mal ohne Signal/Slot-Mechanismus mit
einem Custom-Event implementiert, führt aber exakt zum gleichen
Verhalten. Im dem vom Thread aktivierten Slot bez. EventHandler
lässt sich kein Text auf dem TextEdit ausgeben.
Woran kann das liegen???
/********************************************/
/* MainForm */
/********************************************/
class mainForm:public QWidget
{
Q_OBJECT
public:
mainForm( QWidget* parent, const char* name, WFlags fl);
public slots:
comDataReceived( long readLen);
private:
CComPort* pComPort;
QTextEdit* pTextEdit;
};
/************************************/
/* Initialisierung */
/************************************/
void mainForm::init()
{
pTextEdit = new QTextEdit( this, "textEdit");
pComPort = new CComPort( this);
connect( pComPort, SIGNAL( comInputSignal( long)), this, SLOT( comDataReceived( long)));
}
/************************************/
/* Neue Daten vom COM-Port sind da */
/************************************/
void mainForm::comDataReceived( long al_readLen)
{
char* pInBuf;
QString tempStr;
pInBuf = new char[1000];
pComPort->read( pInBuf);
tempStr.append( (const char*)pInBuf);
cout << tempStr << endl; // OK !
pTextEdit->append( tempStr); // CRASH !
}
/********************************************/
/* Klasse zur Verwaltung eines COM-Ports */
/********************************************/
class CComPort:public QObject
{
Q_OBJECT
public:
CComPort( QWidget* pParentWidget);
read( char* pInBuf);
signals:
comInputSignal( long);
private:
/************************************/
/* Thread zum Lesen des COM-Ports */
/************************************/
class CReaderThread : public QThread
{
public:
CReaderThread( CComPort* pComPort);
run();
}
};
/************************************/
/* */
/************************************/
void CComPort::read( char* pInBuf)
{
// Gelesene Daten an den Aufrufer liefern
}
/************************************/
/* Thread holt Daten vom COM-Port */
/************************************/
void CComPort::CReaderThread::run()
{
long n;
// Lese den Port
n = Anzahl der gelesenen Bytes
// Speichere die Daten in einem Buffer von CComPort
// Signalisiere, dass neue Daten da sind
emit pComPort->comInputSignal( n);
}