Windows und Threading in C++

Hallo,

ich habe hier ein Problem wo ich mal wieder nicht weiter komme. Ich habe eine GUI uber di ich Bytes im Netz hin und her schicke und mir ab und zu Ergebnise ausgeben lasse. Problem ist :

- Ich habe eine GUI und starte die Datenübertragung
- Die GUI ist erstmal blockiert und ich muss warten bis die Übertragung zu Ende ist
- Ist die Übertragung zu Ende, wird mir am ENDE alles an Text welches ich während der Übertragung ausgeben wollte angezeigt.

Ich habe das unter Linux einfach mittels fork gelöst, die GUI ist nicht blockiert und die Textausgabe der Datenübertragung funktioniert, dies wollte ich nun mal für Windows machen, ich habe hier mal eine kurzfassung ohne GUI :

Code:
#include <winsock2.h>
#include <windows.h>
#include <winsock2.h>
#include <iostream>
#include <unistd.h>
#include <stdio.h>

class Connection
{
    public:
     Connection()
     {
         if( (WSAStartup(MAKEWORD(2,0),&wsa)) != 0 )
         {
             printf("+WSAStartup() failed, %lu\n", (unsigned long)GetLastError());
             exit(EXIT_FAILURE);
         }
         std::cout<<"+Socket gestartet...."<<std::endl;
         DWORD threadID = 0;
         HANDLE threadHandle = CreateThread(0,0,webConnect,0,0,&threadID);
     }
     DWORD WINAPI webConnect(LPVOID param)
      {
          createSocket();
          makeConnection();
          sendSomething();
      }
    private:
      void createSocket(void)
      {
          s=socket(AF_INET,SOCK_STREAM,0);
          if(s==INVALID_SOCKET)
          {
              printf("Fehler: Der Socket konnte nicht erstellt werden, fehler code: %d\n",WSAGetLastError());
              exit(EXIT_FAILURE);
          }
          else
          {
              printf("+Socket erstellt!\n");
          }
      }
      void makeConnection(void)
      {
          memset(&addr,0,sizeof(SOCKADDR_IN));
          addr.sin_family = AF_INET;
          addr.sin_port    = htons(25);
          addr.sin_addr.s_addr = inet_addr("217.72.192.157");
          rc = connect(s,(SOCKADDR*)&addr,sizeof(SOCKADDR));
          if(rc == SOCKET_ERROR)
          {
              std::cout<<"+connect gescheitert..."<<std::endl;
              exit(EXIT_FAILURE);
          }
          else
          {
              std::cout<<"+connect erfolgreich..."<<std::endl;
          }
      }
      void sendSomething(void)
      {
          // KOMMUNIKATION
          rc = recv(s,puffer,256,0);
          // Empfangsnachricht empfangen
          write(1,puffer,rc);
          // Server begruessen
          send(s,"HELO smtp.web.de\n",strlen("HELO smtp.web.de\n"),0);
          rc = recv(s,puffer,256,0);
          write(1,puffer,rc);
      }
      long rc;
      SOCKET s;
      SOCKADDR_IN addr;
      WSADATA wsa;
      char puffer[256];
};

int main()
{
    Connection *con = new Connection();
    return 0;
}

Problem ist hier, ich kann der Methode CreateThread nicht die Methode webConnect() uebergeben, da er meckert, diese sei in Connection::webConnect() deklariert, ich kann also nur Funktionen übergeben, keine Methoden aus Klassen.

Eine eine Lösung oder alternative für Threads unter Windows ?
 
Man kann in C++ die Adresse einer Klassenmethode nicht bestimmen. Ausserdem wäre sie nutzlos. Sie ist nur sinnvoll zusammen mit einem Zeiger auf das Datenfeld der Klasse (this-pointer).

Jedesmal wenn eine Klassenmethode aufgerufen wird, übergibt das Programm als ersten Parameter verdeckt einen Zeiger auf das Datenfeld der aktuellen Instanz.

Um das zu simulieren, muss der Thread eine Funktion aufrufen, die als einzigen Parameter den this-pointer hat. Diese Funktion hat einen Zeiger vom Typ "Connection" und initialisiert ihn mit dem übergebenen this-pointer. Dann können aus dieser Funktion heraus sämtliche Klassenmethoden aufgerufen werden.

Code:
Eine statische Klassenmethode definieren. 
Statisch deshalb, damit man die Adresse bestimmen kann :

static DWORD __stdcall  thrproc_static (void *self) {
 Connection *c = (Connection *) self;
 c -> webConnect (0);
 return 0x0000;
}

CreateThread () nun so aufrufen :

HANDLE threadHandle = CreateThread(0,0,thrproc_static,this,0,&threadID);
P.S.:
Mit dieser Lösung kann man auch in einer WinGUI sämtliche "WndProc"s in ihre jeweiligen Klassen verbannen. Dann bleibt im Quelltext nichts globales mehr übrig. Darüber freuen sich alle C++-Pedanten. :-)
 
Zurück
Oben