AnfängerProbleme mit Threads



  • Hallo,
    mein Programm liest über die serielle schnittstelle aus einem Gerät Messwerte und stellt Sie in einem Dialog grafisch dar.
    Die Kommunikation möchte ich nun in einen eigenen Thread packen.

    Dazu hab ich nun neue Klasse erstellt, CComThread, abgeleitet von CWinThread und im header folgendes deklariert:

    virtual int Run();
    CDisplay* m_dialogvar;
    CDisplay* m_pOwner;
    void SetOwner(CDisplay* pOwner) {m_pOwner = pOwner;}
    

    Die Hauptklasse ist wohl der Dialog,in dem Messergebnisse dargestellt werden, CDisplay.

    void CDisplay::DisplayCom()
    {
    	class CComThread;
    	CComThread* m_xDisplayThread;
    
    	m_xDisplayThread = (CComThread*)
    	AfxBeginThread(RUNTIME_CLASS(CComThread), NULL, 0, CREATE_SUSPENDED);
    	m_xDisplayThread->SetOwner(this);
    	m_xDisplayThread->ResumeThread();
    }
    

    habe dann mal compiliert und kriege den Error: Verwendung des undefinierten Typs "(void) CDisplay::DisplayCom::ComThread"

    Was habe ich denn falsch gemacht??


  • Mod

    Wenn Du es so machen willst musst Du CComThread von CWinThread ableiten, wie es auch in der Beschreibung steht. Zudem musst Du diese Klasse mit DECLARE_DYNCREATE/IMPLEMENT_DYNCREATE versehen!



  • Ah, okay versuch das mal, wirst aber sicher bald wieder von mir hören.



  • DECLARE_DYNCREATE/IMPLEMENT_DYNCREATE steht in ComThread.cpp und ComThread.h schon drin. Der Fehler ist woanders.



  • Kann mir jemand sagen wo der Fehler liegt?



  • muss ich eigentlich einen arbeitsthread oder einen benutzerthread für diese aufgabe erstellen?



  • Lass mal das class CComThread; da weg.



  • Hab das jetzt anders gemacht. Hab da aber auch jede Menge Probleme.

    UINT ThreadFunc( LPVOID pParam )
    {	
    	Hex2Float hex2float;
    
    	MyCOM.DC_Com_Properties.BaudRate = 1200;
    	MyCOM.DC_Com_Properties.ByteSize = 8;
    	MyCOM.DC_Com_Properties.Parity = NOPARITY;
    	MyCOM.DC_Com_Properties.StopBits =1;
    	MyCOM.DC_Com_Properties.fOutxCtsFlow=0;
        MyCOM.DC_Com_Properties.fOutxDsrFlow=0;
    }
    
    void CDisplay::DisplayCom()
    {	
    CWinThread *pThread = AfxBeginThread(ThreadFunc, GetSafeHwnd(),   THREAD_PRIORITY_NORMAL);
    }
    

    MyCOM hab ich in der HeaderDatei von Display deklariert.
    Jetzt krieg ich einen LinkerError.
    "MyCOM ist bereits in CommPort.obj definiert"



  • maRKus23 schrieb:

    MyCOM hab ich in der HeaderDatei von Display deklariert.

    Offenbar hast du es nicht nur deklariert, sondern auch definiert. Und das ist auch das Problem. Man definiert keine Variablen in Headerdateien.



  • Das Problem habe ich auch mit anderen Variablen, zb. ComFlag.
    In meiner Headerdatei steht dann

    int ComFlag;
    

    ist das dann eine Deklaration oder eine Definition?
    ich war immer der Ansicht das wäre eine Deklaration.
    Wie kann ich nun globale Variablen deklarieren und definieren, die sowohl in CDisplay::DisplayCom() und in meiner ThreadFunction UINT ComThreadProc(LPVOID pParam) zum Einsatz kommen?



  • maRKus23 schrieb:

    In meiner Headerdatei steht dann

    int ComFlag;
    

    ist das dann eine Deklaration oder eine Definition?

    Das ist eine Definition.

    Wie kann ich nun globale Variablen deklarieren und definieren, die sowohl in CDisplay::DisplayCom() und in meiner ThreadFunction UINT ComThreadProc(LPVOID pParam) zum Einsatz kommen?

    Deklarieren kannst du die Variable mit extern, also

    extern int ComFlag;
    

    in der Headerdatei.

    Dann musst du die Variable noch in einer Quellcodedatei definieren. Dabei kannst du sie dann auch gleich initialisieren.



  • probier ich mal aus, du hörst sicher gleich wieder von mir. ich habe noch jede menge probleme, an denen ich fast verzweifle. 😕



  • okay hab das dann soweit erledigt, allerdings kann ich aus dem Thread heraus keine Bytes mehr an mein Gerät senden.

    UINT ComThreadProc(LPVOID pParam)    //Thread funktioniert Kommunikation nicht
    {
    	 BOOL bCancel = FALSE;
    	 BYTE Message5[2] = {0x10, 0x0c};
    	 BYTE Response2[200];
    
              SerialPort MyCOM;     
    
    	while(bCancel == FALSE)
    	 {
    		MyCOM.WriteNBytes (2, (BYTE*) Message5);
    		Sleep(3000);
    		MyCOM.ReadNBytes(MyCOM.BytesInQueue(), (BYTE*) Response2);
              }
    
    void CDisplay::DisplayCom()
    {		
    	Hex2Float hex2float;
    	SerialPort MyCOM;
    
    	MyCOM.DC_Com_Properties.BaudRate = 1200;
    	MyCOM.DC_Com_Properties.ByteSize = 8;
    	MyCOM.DC_Com_Properties.Parity = NOPARITY;
    	MyCOM.DC_Com_Properties.StopBits =1;
    	MyCOM.DC_Com_Properties.fOutxCtsFlow=0;
        MyCOM.DC_Com_Properties.fOutxDsrFlow=0;
    
    	BYTE Message0[10] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x02, 0x81, 0x00,0x00, 0x83};
    	BYTE Message1[7] = {0x20, 0x70, 0x00, 0x00, 0x00, 0x00, 0x90};
    	BYTE Message2[2] = {0x10, 0x01};
    	BYTE Message3[2] = {0x10, 0x02};
    	BYTE Message4[7] = {0x20, 0x1E, 0x00, 0x00, 0x00, 0x00, 0x3E};
    
    	BYTE Response[200];
    
    	MyCOM.Open(2);			  // open port  
    	MyCOM.ControlDTR(true);   // power on  
    	Sleep (1500);
    
    	MyCOM.WriteNBytes (10, (BYTE*) Message0);	//Hart Kommando
        Sleep (1000);
    	MyCOM.WriteNBytes (7, (BYTE*) Message1);	//State
        Sleep (500);
    	MyCOM.ControlDTR(false);   // power off  
    	MyCOM.ControlDTR(true);   // power on  
    	Sleep (1500);
    	MyCOM.WriteNBytes (2, (BYTE*) Message2);	//upper value
    	Sleep (1000);
    	MyCOM.WriteNBytes (2, (BYTE*) Message3);	//lower value
    	Sleep (1000);
    	MyCOM.WriteNBytes (7, (BYTE*) Message4);	//current 4mA
    	Sleep (2000);
    
    MyCOM.ReadNBytes(MyCOM.BytesInQueue(), Response);
    

    Was habe ich denn im Thread falsch gemacht das die Kommunikation nicht mehr geht?

    in der headerdatei habe ich folgendes

    extern SerialPort MyCOM;
    


  • Okay die Kommunikation funktioniert jetzt.
    Jetzt muss ich nur noch den Wert in meinem Dialog ausgeben.

    void SetPVTemperature(float fTemperaturePV)
    {
    	char buffer[20];
    	CString szTemperature = "";
    	float fPercentMeasuring = 0;
    
    	CString szPercentMeasuring;
    	CStatic m_Static_fPrimaryValue;
    
    	_gcvt(fTemperaturePV, 5, buffer);
    	 szTemperature= buffer;
    	 szTemperature.Replace('.',',');
    	 m_Static_fPrimaryValue.SetWindowText(szTemperature);
    }
    
    UINT ComThreadProc(LPVOID pParam)
    {
    hex2float.Hex[0] = Response2[j+2];			
    hex2float.Hex[1] = Response2[j+3];
    hex2float.Hex[2] = Response2[j+4];
    hex2float.Hex[3] = Response2[j+5];
    fTemperaturePV = hex2float.fValue;
    SetPVTemperature(fTemperaturePV);
    }
    

    so wollte ich SetPVTemperature() aufrufen und die Variable fTemperaturePV übergeben und anschließend im Dialog darstellen.
    Nach m_Static_fPrimaryValue.SetWindowText(szTemperature); bricht er aber das Programm ab.

    der stackpointer(?) steht dann in dbgrpt.c im Code

    _CRTIMP void _cdecl_CrtDbgBreak(void)
    {
       DebugBreak;
    }
    

    Ich versteh dieses Code Segment nicht.
    Wer kann mir weiterhelfen?

    [/cpp]



  • Also mein Dialog ist nnicht richtig initialisiert zu dem Zeitpunkt wenn ich SetWindowText ausführe.
    Wie muss ich den Dialog richtig initialisieren?



  • Hilfe, bitte postet mir mal ein Beispiel wie man zwischen dem Hauptthread und dem Arbeitsthread kommunizieren kann.
    Möchte doch nur eine Funktion aus dem Hauptthread aufrufen und ihr eine Variable übergeben.


Anmelden zum Antworten