tutorials.de Buch-Aktion 05/2012
Like Tree1Danke
  • 1 Beitrag von Cromon
ERLEDIGT
JA
ANTWORTEN
11
ZUGRIFFE
4365
EMPFEHLEN
  • An Twitter übertragen
  • An Facebook übertragen
AUF DIESES THEMA
ANTWORTEN
  1. #1
    colt4ever Tutorials.de Gastzugang
    Hallo,
    ich würde gerne ein Spiel programmieren das mit Threads läuft.

    ich habe eine Funktion
    Code :
    1
    
    void setBallPos(int *ball_pos);

    und möchte diese mit der Threadfunktion
    Code :
    1
    2
    3
    4
    
    int ball_pos = 0;
    ...
    _beginthread(setBallPos(&ball_pos),0,NULL);
    ...

    aufrufen.
    Ich weiss, dass normalerweise die Funktion setBallPos einen void * Parameter bekommen muss, aber ich benötige diese int * Parameter (möchte nicht globale Variablen verwenden).

    Wess jemand wie ich das hinbekomme, oder gibt es da eine bessere Threadfunktion als _beginthread()
     

  2. #2
    Registriert seit
    Apr 2002
    Ort
    Delmenhorst (Niedersachsen)
    Beiträge
    3.567
    moin


    Hä?!

    Was hat das mit der _beingthread zu tun wenn dein setBallPos einen PArameter bekommen muss?


    mfg
    umbrasaxum
     

  3. #3
    colt4ever Tutorials.de Gastzugang
    Es kommt immer ein Fehler bei dem steht der Prototyp der Funktion von _beginthread(...), wenn ich es mit meiner set_Ball Funktion probiere.
    Aber wenn ich meine Funktion auf void set_ball(void *) umändere funktioniert es.
     

  4. #4
    Registriert seit
    Apr 2002
    Ort
    Delmenhorst (Niedersachsen)
    Beiträge
    3.567
    moin


    Hast du schon versucht, wenn du deine Funktion nach void set_ball(void *) geändert hast, int *ball_pos "rein zu casten"?


    Hab hier noch was aus der MSDN, da wird mit einem Parameter anders umgegangen:
    Code :
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    
    // crt_BEGTHRD.C
    // compile with: /MT /D "_X86_" /c
    #include <windows.h>
    #include <process.h>    /* _beginthread, _endthread */
    #include <stddef.h>
    #include <stdlib.h>
    #include <conio.h>
     
    void Bounce( void *ch );
    void CheckKey( void *dummy );
     
    /* GetRandom returns a random integer between min and max. */
    #define GetRandom( min, max ) ((rand() % (int)(((max) + 1) - (min))) + (min))
     
    BOOL repeat = TRUE;     /* Global repeat flag and video variable */
    HANDLE hStdOut;         /* Handle for console window */
    CONSOLE_SCREEN_BUFFER_INFO csbi;    /* Console information structure */
     
    int main()
    {
        CHAR    ch = 'A';
     
        hStdOut = GetStdHandle( STD_OUTPUT_HANDLE );
     
        /* Get display screen's text row and column information. */
       GetConsoleScreenBufferInfo( hStdOut, &csbi );
     
        /* Launch CheckKey thread to check for terminating keystroke. */
        _beginthread( CheckKey, 0, NULL );
     
        /* Loop until CheckKey terminates program. */
        while( repeat )
        {
            /* On first loops, launch character threads. */
            _beginthread( Bounce, 0, (void *) (ch++)  );
     
            /* Wait one second between loops. */
            Sleep( 1000L );
        }
    }
     
    /* CheckKey - Thread to wait for a keystroke, then clear repeat flag. */
    void CheckKey( void *dummy )
    {
        _getch();
        repeat = 0;    /* _endthread implied */
     
    }
     
    /* Bounce - Thread to create and and control a colored letter that moves
     * around on the screen.
     *
     * Params: ch - the letter to be moved
     */
    void Bounce( void *ch )
    {
        /* Generate letter and color attribute from thread argument. */
        char    blankcell = 0x20;
        char    blockcell = (char) ch;
        BOOL    first = TRUE;
       COORD   oldcoord, newcoord;
       DWORD   result;
     
     
        /* Seed random number generator and get initial location. */
        srand( _threadid );
        newcoord.X = GetRandom( 0, csbi.dwSize.X - 1 );
        newcoord.Y = GetRandom( 0, csbi.dwSize.Y - 1 );
        while( repeat )
        {
            /* Pause between loops. */
            Sleep( 100L );
     
            /* Blank out our old position on the screen, and draw new letter. */
            if( first )
                first = FALSE;
            else
             WriteConsoleOutputCharacter( hStdOut, &blankcell, 1, oldcoord, &result );
             WriteConsoleOutputCharacter( hStdOut, &blockcell, 1, newcoord, &result );
     
            /* Increment the coordinate for next placement of the block. */
            oldcoord.X = newcoord.X;
            oldcoord.Y = newcoord.Y;
            newcoord.X += GetRandom( -1, 1 );
            newcoord.Y += GetRandom( -1, 1 );
     
            /* Correct placement (and beep) if about to go off the screen. */
            if( newcoord.X < 0 )
                newcoord.X = 1;
            else if( newcoord.X == csbi.dwSize.X )
                newcoord.X = csbi.dwSize.X - 2;
            else if( newcoord.Y < 0 )
                newcoord.Y = 1;
            else if( newcoord.Y == csbi.dwSize.Y )
                newcoord.Y = csbi.dwSize.Y - 2;
     
            /* If not at a screen border, continue, otherwise beep. */
            else
                continue;
            Beep( ((char) ch - 'A') * 100, 175 );
        }
        /* _endthread given to terminate */
        _endthread();
    }


    mfg
    umbrasaxum
    Geändert von Tobias K. (19.02.05 um 10:55 Uhr)
     

  5. #5
    colt4ever Tutorials.de Gastzugang
    Danke für dieses Beispiel. Ich hab es vollbracht.

    Code :
    1
    
    _beginthread(set_ball,0,(void *)ball_pos);

    und es geht.
     

  6. #6
    colt4ever Tutorials.de Gastzugang
    Hab es für Ping Pong benötigt.

    Ups, vergessen zu schliessen.
     

  7. #7
    hendrik100 hendrik100 ist offline Grünschnabel
    Registriert seit
    Aug 2006
    Beiträge
    3
    ich habe so ziemlich genau dasselbe problem, nur das ich dem thread nicht nur einen, sondern mehrere parameter übergeben möchte!
    mit einem übergabeparameter funktioniert dass ganz gut, aber mit mehreren bekomme ich das nicht hin!
    könnt ihr mir da weiter helfen?
     

  8. #8
    Registriert seit
    Jan 2003
    Ort
    Roßdorf (Hessen)
    Beiträge
    196
    nimm eine struct und übergebe die adresse der struct in deine thread funktion
     

  9. #9
    Eva80 Tutorials.de Gastzugang
    Hallo,

    ich habe ebenfalls ein Problem mit _beginthread. Und zwar müsste ich an meine Funktion nachrichten_holen ein Formularfeld übergeben.
    Befehl:
    _beginthread(nachrichten_holen, 0, (void *)Alle_Nachrichten_textBox);

    Gibt folgende Fehlermeldung:
    error C2440: 'Typumwandlung': 'System::Windows::Forms::TextBox ^' kann nicht in 'void *' konvertiert werden

    Was kann ich tun, bzw. wie muss ich mein Formularfeld konvertieren dass es klappt? Ziel ist es, in der Funktion in das Formularfeld etwas einzutragen.

    Wäre für jede Hilfe sehr dankbar! Gruß Eva
     

  10. #10
    Cromon Cromon ist offline Mitglied Brillant
    Registriert seit
    Apr 2008
    Beiträge
    819
    Da wirst du sowieso Probleme bekommen. Verwaltete CLR-Komponenten dürfen nicht einfach so willkürlich im unverwalteten Code verwendet werden. Verwende verwaltete Threads über System::Threading und bedenke, dass du auf Controls (TextBox ist ein Control) nur in dem Thread zugreiffen kannst in dem sie erstellt wurde. Versuche ohne ein delegat und Invoke auf das Control zuzugreiffen werden eine Exception werfen.
    eva80 bedankt sich. 

  11. #11
    eva80 eva80 ist offline Grünschnabel
    Registriert seit
    Mar 2010
    Beiträge
    1
    Hallo Cromon,

    vielen Dank für Deine schnelle und hilfreiche Antwort. Ich habe ein bißchen rumprobiert und habe folgenden Code gefunden, der den delegate-Befehl sehr gut beschreibt. Ich habe daraufhin mein Programm umgeschrieben, dass das Feld nicht mehr über einen Übergabeparameter sondern damit gefüllt wird. Hier der Beispielcode, falls noch mehr damit Probleme haben.
    Man braucht ein Formular mit dem Textfeld "chat_textBox" und nem Button "Button1". Gehört alles in die Klassendokumentation des Formulars.
    Code :
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    
    public:
       void DoWork()    // Ursprüngliche Funktion
       {
           this->chat_textBox->AppendText("Das ist der Text aus DoWork");
           this->chat_textBox->AppendText(Environment::NewLine);
       }
     
       void DoWork2()   // Neue Funktion
       {
           this->chat_textBox->Invoke(gcnew new_DoWork_delegate( this, &multithreads::Form1::new_DoWork));
       }
       delegate void new_DoWork_delegate();
       void new_DoWork()
       {
           this->chat_textBox->AppendText("Das ist der Text aus new_DoWork");
           this->chat_textBox->AppendText(Environment::NewLine);
       }
     
        private: System::Void button1_Click(System::Object^  sender, System::EventArgs^  e) {
       DoWork();
       // DoWork2 im Hauptthread starten
       DoWork2();
     
    // Neuen Thread erstellen für DoWork2
       this->chat_textBox->AppendText("Neuer Thread wird gestartet");
       this->chat_textBox->AppendText(Environment::NewLine);
     
       ThreadStart^ thread1s = gcnew ThreadStart( this, &Form1::DoWork2 );
       Thread^ thread1 = gcnew Thread( thread1s );
       thread1->Start();
       }

    Natürlich war es das für mich noch nicht. Ich muss einen Chatserver programmieren und wollte im Client einen Hintergrundthread erstellen, der in einer Endlosschleife die Nachrichten vom Server holt und in dem Textfeld ausgiebt. Leider funktioniert das nicht, wenn ich die Methode als Endlosschleife laufen lasse, baut er das Ausgabeformular nicht mehr auf. Wenn ich im Hintergrundthread nur einen Durchlauf in der Schleife einstelle, dann klappt es. Also anscheinend läuft bei der Endlosschleife nur noch der neue Thread und der ursprüngliche nicht mehr!? Muss ich 2 neue Threads erstellen?
    Wäre super, wenn nochmal jemand einen Tipp hätte.
    Danke und Gruß Eva - jetzt angemeldet
    Geändert von eva80 (14.03.10 um 17:17 Uhr)
     

  12. #12
    Cromon Cromon ist offline Mitglied Brillant
    Registriert seit
    Apr 2008
    Beiträge
    819
    Hallo Eva!

    Hast du dazu vielleicht noch ein bisschen Code? Grundsätzlich sollten Schleifen in einem anderen Thread den Dialog nicht blockieren. Vielleicht wäre es jetzt auch gut ein neues Thema zu starten im .NET-Forum?

    Gruss
    Cromon
     

Ähnliche Themen

  1. Allegro kennt _beginthread nicht
    Von Windhund im Forum C/C++
    Antworten: 3
    Letzter Beitrag: 13.05.09, 22:01
  2. wie _beginthread, socket abschießen ?
    Von cyberds19 im Forum VisualStudio & MFC
    Antworten: 2
    Letzter Beitrag: 31.07.08, 17:25
  3. problem mit _beginthread funktion
    Von Nasenbrecher im Forum VisualStudio & MFC
    Antworten: 4
    Letzter Beitrag: 03.11.05, 19:55
  4. _beginthread und void*
    Von unmatrix im Forum VisualStudio & MFC
    Antworten: 3
    Letzter Beitrag: 04.10.05, 16:23
  5. Antworten: 6
    Letzter Beitrag: 13.06.02, 12:29