Event-Funktionen dynamisch zuweisen
-
Hallo,
Ich verwende die TClientSocket Komponente um mich zu einer Server-Anwendung zu verbinden. Da mehrere Verbindungen gleichzeitige realisiert werden sollen passiert das in mehreren unterschiedlichen Threads. Deshalb muss ich das TClientServer-Objekt jeweils beim starten des Threads neu erstellen und beim beenden freigeben. Mein Problem ist jetzt wie kann ich die Prozeduren für die Ereignisse OnConnect oder OnRead zum Beispiel zuweisen, damit die Ereignisse abgefangen werden können? Ich hab es zunächst mal so versucht:
ClientSocket1 = new TClientSocket(NULL); ClientSocket1->Active = false; ClientSocket1->ClientType = ctBlocking; ClientSocket1->Port = 1860; ClientSocket1->Host = "127.0.0.1"; ClientSocket1->OnConnect = ClientSocket1Connect; ClientSocket1->Open();
In der gleichen Unit gibt es dann eine Funktion die das OnConnect Ereignis abfangen soll:
void __fastcall ClientSocket1Connect(TObject *Sender, TCustomWinSocket *Socket) { }
Die Zuweisung der OnConnect-Funktion von oben scheint aber falsch zu sein sagt der bcb (unterschiedliche Typen ect). Weiss jemand was das falsch ist und wie ich es richtig machen muss?
Danke Markus
-
Du hast den Eintrag in der Header vergessen
http://www.marquardtnet.info/cecke/quickies.1/1_quicky_21.html
-
Danke für die Antwort
Das Problem ist aber das es sich um eine eigenständige Unit handelt in der die Komponente erzeugt wird. Das heisst das TClientSocket in diesem Fall kein Mitglied von Form1 oder TForm ist sondern im Header der entsprechenden Unit so deklariert wird:
TClientSocket *ClientSocket1;
auch die OnConnect-Funktion habe ich im Header der Unit deklariert, natürlich nicht unter __published weil es eben keine Class TForm in der Unit gibt sondern ganz normal als Funktion:
void __fastcall ClientSocket1Connect(TObject *Sender, TCustomWinSocket *Socket);
Trotzdem krieg ich ja die Fehlermeldung, muss ich das dann irgendwie anders deklarieren?
-
Hallo
und genau das geht nicht.
Die Events der VCL erwarten immer eine Memberfunktion einer Klasse (muß keine TForm sein, hauptsache zu einer Klasse zugehörend).Desweiteren ist die offenbar (globale) Deklaration
TClientSocket *ClientSocket1;
erstens ein Standardname und damit nicht aussagekräftig und zweitens keine optimale Lösung.
Wahrscheinlich kannst du beide Probleme gleichzeitig und elegant lösen, in dem du sowohl den Socket als auch die Eventmethode einfach in einer eigenen kleinen Klasse kapselst. Die klasse kann dann auch für das Erstellen und Löschen (nicht vergessen!) des Sockets dienen.
bis bald
akari
-
So ich hab jetzt mal alles in eine eigene Klasse gepackt aber der Fehler bleibt der selbe, deswegen poste ich jetzt nochmal den aktuellen Stand und die Fehlermeldung.
Also die Klassen-Deklaration im Header sieht so aus:class Socket { private: public: void __fastcall ClientSocket1Connect(TObject *Sender, TCustomWinSocket *Socket); TClientSocket *ClientSocket1; };
Dann wird nochmal der Aufruf:
int __fastcall Sock1 (void *p) { Uebergabe *d = (Uebergabe *) p; Socket *Socket1 = new Socket; try { Socket1->ClientSocket1 = new TClientSocket(NULL); Socket1->ClientSocket1->Active = false; Socket1->ClientSocket1->ClientType = ctBlocking; Socket1->ClientSocket1->Port = 1860; Socket1->ClientSocket1->Host = "127.0.0.1"; Socket1->ClientSocket1->OnConnect = Socket::ClientSocket1Connect; Socket1->ClientSocket1->Open(); Idglobal::Sleep(3000);
und dann die Eventmethode:
void _fastcall Socket::ClientSocket1Connect(TObject *Sender, TCustomWinSocket *Socket) { }
und als Fehlermeldung vom BCB bekomme ich in der Zeile
Socket1->ClientSocket1->OnConnect = Socket::ClientSocket1Connect;
dieses hier:
[C++ Error] SockKonst.cpp(199): E2034 Cannot convert 'void (_fastcall Socket::*)(TObject *,TCustomWinSocket *)' to 'void (_fastcall * (_closure )(TObject *,TCustomWinSocket *))(TObject *,TCustomWinSocket *)'
werde daraus irgendwie nicht schlau aber es will immer noch nicht klappen.
-
Hallo
due Funktion Sock1 (fällt dir da wirklich kein treffender Name ein?!) muß natürlich auch ein Member der Klasse Socket sein.
Desweiteren sorgst du hoffentlich auch dafür, das die mit new angelegte Instanz auch wieder nach Gebrauch mit delete gelöscht wird.
bis bald
akari
-
Habe es auch mal nachgestellt aber es geht immer noch nicht ?
gleicher Fehler wie bisher ...
(header)
class SocketABC
{
private:
public:
void __fastcall ClientSocket1Connect(TObject *Sender,TCustomWinSocket *Socket);
void __fastcall Sock1(void);
TClientSocket *ClientSocket1;
};
(c++)
void __fastcall Sock1(void)
{
SocketABC *Socket1 = new SocketABC;Socket1->ClientSocket1 = new TClientSocket(NULL);
Socket1->ClientSocket1->Active = false;
Socket1->ClientSocket1->ClientType = ctBlocking;
Socket1->ClientSocket1->Port = 1860;
Socket1->ClientSocket1->Host = "127.0.0.1";
Socket1->ClientSocket1->OnConnect = SocketABC::ClientSocket1Connect;
Socket1->ClientSocket1->Open();
Sleep(3000);
}
//---------------------------------------------------------------------------
void _fastcall SocketABC::ClientSocket1Connect(TObject *Sender,TCustomWinSocket *Socket)
{
MessageBox(NULL, HostServerName,"Connected to.…",MB_OK);
}Wäre echt schön wenn DU es dir nochmal anschauen könntest..
-
Bei der Definition muß der Klassenname hin, also:
void __fastcall SocketABC::Sock1() // (void) ist in C++ nicht nötig { // ... }