TThread einbinden - Fehler E2268 Aufruf der undefinierten Funktion
-
Hallo,
habe seit Stunden ein Problem und verzweifel bald:
Mit Neu lege ich zwei neue Thread-Objekte an; eines nenne
ich ThreadClients und das andere ThreadSenden.Das erste klappt wunderbar; beim zweiten kommt immer der E2268 Fehler.
**Main_NH3.cpp(4115): Analyse von: void _fastcall TForm1::frm1_tmrStartTimer(TObject
[C++ Fehler] Main_NH3.cpp(4275): E2268 Aufruf der undefinierten Funktion 'ThreadSenden'
Vollständiger Parser-Kontext
Main_NH3.cpp(4269): Analyse von: void _fastcall TForm1::frm1_tmrThreadATimer(TObject
**
Auch aus dem Projekt entfernen und neu einbinden bringt kein Erfolg!?Die Threads starte ich jeweils separat in einem Timer.
// TIMER T void __fastcall TForm1::frm1_tmrThreadCTimer(TObject *Sender) {try { // Fehlerroutine Start Form1->frm1_tmrThreadC->Enabled=false; // und Timer stoppen // CLIENTEN ZÄHLEN ThreadClients(false); // Thread starten (noch nicht starten=true) // AUSGANG } catch(Exception& e) { MessageBox(NULL, e.Message.c_str(), "TForm1::frm1_tmrThreadCTimer()", MB_OK); } // Fehler anzeigen } void __fastcall TForm1::frm1_tmrThreadATimer(TObject *Sender) {try { // Fehlerroutine Start Form1->frm1_tmrThreadA->Enabled=false; // und Timer stoppen // BENACHRICHTIGEN ABSETZEN ThreadSenden(false); // Thread starten (noch nicht starten=true) } catch(Exception& e) { MessageBox(NULL, e.Message.c_str(), "TForm1::frm1_tmrThreadATimer()", MB_OK); } // Fehler anzeigen }Habe alles mögliche probiert und komme nicht mehr weiter...
Hier mal der Code von ThreadSenden.cpp:
//--------------------------------------------------------------------------- #include <inifiles.hpp> // INI Files #include <vcl.h> #pragma hdrstop #include "Main_NH3.h" // Form1 #include "Thread_Senden.h" // Thread 2 #pragma package(smart_init) //--------------------------------------------------------------------------- __fastcall ThreadSenden::ThreadSenden(bool CreateSuspended) : TThread(CreateSuspended) { switch(Form1->iThPrioA) { // Thread wie ausführen... case 0: Priority=tpIdle; break; // Prio nur wenn System im Leerlauf ist case 1: Priority=tpLowest; break; // Prio 2 Stufen unter Normal case 2: Priority=tpLower; break; // Prio 1 Stufe unter Normal case 3: Priority=tpNormal; break; // Prio ist Normal case 4: Priority=tpHigher; break; // Prio 1 Stufe über Normal case 5: Priority=tpHighest; break; // Prio 2 Stufen über Normal case 6: Priority=tpTimeCritical; break; // Prio Höchste default: Priority=tpIdle; break; // Prio nur wenn System im Leerlauf ist } // endswitch(iPrio //FatalException=TObject...; // bei Fehler autom. freigeben //OnTerminate=ThreadDelete; // und freigeben starten FreeOnTerminate=true; // nach Beendigung autom. freigeben } //--------------------------------------------------------------------------- //--- THREADS --- //--------------------------------------------------------------------------- void __fastcall ThreadSenden::Execute() {try { // Fehlerroutine Start while (!ThreadSenden::Terminated) { // abarbeiten bis Abbruchbefehl kommt Synchronize(Versenden); // und synchronisiert los //Versenden(); // nicht synchronisiert los if(ThreadSenden::Terminated==true) { break; } // Abbruch raus break; // und fertig } // ende while() //-----------------------------------------------------------------------------// THREAD ENDE Form1->frm1_tmrThreadA->Enabled=Terminated==false; // und Timer wieder starten (falls nicht Abbruch) } catch(Exception& e) { MessageBox(NULL, e.Message.c_str(), "TThreadSenden::Execute()", MB_OK); } // Fehler anzeigen } //--------------------------------------------------------------------------- //--- FUNKTIONEN IM THREAD --- //--------------------------------------------------------------------------- // FUNKTION D AnsiString DatenPipe(int p1, int p2, AnsiString pt1, AnsiString pt2) {try { // Fehlerroutine Start Integer i2,i3; AnsiString z1,z2; // Vars definieren if(pt1.Length()==0) { pt1="||"; } // Stringvorgabe korrigieren z1=pt1; // und übergeben switch(p1) { // was machen? case 1: // AUSLESEN STRING case 3: // AUSLESEN INTEGER for(int i1=1;i1<=p2;i1++) { // x. Pipe suchen i2=z1.AnsiPos("|"); // Pipe suchen if(i2==0) { z1=z1+"|"; i2=z1.AnsiPos("|"); } // keines gefunden, neues Pipe anhängen z1=z1.SubString(i2+1,9999); // String ab Pipe+1 abschneiden } // ende for(int i2) i2=z1.AnsiPos("|"); // noch nächstes Pipe suchen z1=z1.SubString( 1,i2-1); // und bis nächstes Pipe den Inhalt ausschneiden if(pt2=="!!") { z1=z1.Trim(); } // ohne Leerstellen zurückgeben if(p1==3 && z1.Length()==0) { z1="0"; } // Rückgabe für Integer (leerer String gibt Fehlermeldung!) return z1; // und Inhalt zurückgeben case 2: // SCHREIBEN case 4: // SCHREIBEN MIT FEHLERHINWEIS z2=""; // String vorbereitend löschen for(int i1=1;i1<=p2;i1++) { // x. Pipe suchen i2=z1.AnsiPos("|"); if(i2==0) { z1="|"; i2=1; } // Pipe suchen und ggfs. anhängen z2=z2+z1.SubString(1, i2); // und Rest merken z1=z1.SubString(i2+1,9999); // String ab Pipe+1 abschneiden } // ende for(int i2) i2=z1.AnsiPos("|"); // noch nächstes Pipe suchen z1=z2+pt2+z1.SubString(i2, pt1.Length()); // und pt2 einsetzen und ab nächstem Pipe anhängen return z1; // und Inhalt zurückgeben } // ende switch(p1 return ""; // Standardrückgabe } catch(Exception& e) { MessageBox(NULL, e.Message.c_str(), "TThreadSenden::DatenPipe()", MB_OK); return ""; } // Fehler anzeigen } // FUNKTION V void __fastcall ThreadSenden::Versenden() // MESSAGE-FUNKTIONEN {Form1->frm1_btn8_AktuellClick(0); // und los } // FUNKTION Z AnsiString ZeitStempel(int p1,AnsiString pt1) {try { // Fehlerroutine Start AnsiString z1; // Vars definieren TDateTime DateTime=Now(); // Datum und Uhrzeit speichern switch(p1) { // was zurückgeben case 0: // KOMPLETTE ZEIT case 1: z1=FormatDateTime("dd.mm.yyyy, hh:nn:ss" ,DateTime); break; // KOMPLETTE ZEIT case 2: z1=FormatDateTime("dd.mm.yyyy" ,DateTime); break; // NUR DATUM; case 3: z1=FormatDateTime("hh:nn:ss" ,DateTime); break; // NUR UHRZEIT; case 4: z1=FormatDateTime("dd.mm.yyyy, hh:nn" ,DateTime); break; // KURZFORM case 5: z1=FormatDateTime("yyyy-mm-dd" ,DateTime); break; // NUR DATUM FÜR DATEI; case 6: z1=FormatDateTime("dd.mm.yyyy hh:nn:ss" ,DateTime); break; // KOMPLETTE ZEIT OHNE KOMMA case 7: z1=FormatDateTime("yyyy-mm-dd hh-nn-ss" ,DateTime); break; // LOGBUCHSTEMPEL; case 8: z1=FormatDateTime("yyyy-mm" ,DateTime); break; // NUR DATUM FÜR DATEI; case 9: z1=FormatDateTime("yyyy-mm-dd hh-nn-ss-zzz" ,DateTime); break; // LOGBUCHSTEMPEL MIT MILLISEKUNDEN; } // ende p1 return z1+" "; // und Rückgabe der Zeit } catch(Exception& e) { MessageBox(NULL, e.Message.c_str(), "TThreadSenden::ZeitStempel()", MB_OK); return ""; } // Fehler anzeigen }und der zugehörige Header:
//--------------------------------------------------------------------------- #ifndef Thread_SendenH #define Thread_SendenH //--------------------------------------------------------------------------- #include <Classes.hpp> AnsiString DatenPipe(int p1, int p2, AnsiString pt1, AnsiString pt2); // Funktion definieren AnsiString ZeitStempel(int p1, AnsiString pt1); // Funktion definieren //--------------------------------------------------------------------------- class ThreadSenden : public TThread { private: protected: void __fastcall Execute(); void __fastcall Versenden(); // Funktion deklarieren public: __fastcall ThreadSenden(bool CreateSuspended); }; //--------------------------------------------------------------------------- #endifFalls die Threads inhaltlich Fehler haben oder umständlich sind,
dann bitte ich um Nachsehen. Das Thema Threads ist für mich ziemlich neu
Danke für jeden Tipp.
Gruss Stefan Scholz
-
Hallo
Der Fehler selber besagt das du wohl ein include auf die Unit mit ThreadSenden vergessen hast.
Allerdings wird das nicht alle Probleme beheben, denn du hast ein Klasse ThreadSendern, keine Funktion. Du must erst eine Instanz der Klasse erstellen und dann kannst du für die Instanz eine Methode aufrufen.
Bitte schau dir erstmal ein Tutorial über Threads an. Am besten auch eins über OOP.bis bald
akari
-
Hallo Akari
ich Esel hatte den Include in meiner Main.h vergessen und einfach
nicht dran gedacht, weil ich dachte er würde es beim Einbinden als
neues Object automatisch machen (der erste Thread war von früher
noch included; daher lief der)
Danke für den Tip;
Stefan