2013-03-04 2 views
0

J'ai essayé de créer un fil à l'intérieur d'une classe et j'ai eu une erreur. Je me demandais juste s'il y a moyen de contourner cela ou dois-je utiliser des discussions au sein de int main() seulement?CreateThread dans une erreur de classe: l'argument de type 'DWORD (windows_thread ::) (void *)' ne correspond pas à 'DWORD (*) (void *)'?

C:\windows_thread_2\windows_thread_2.cpp||In member function 'void windows_thread::thread()':| 
C:\windows_thread_2\windows_thread_2.cpp|24|error: argument of type 'DWORD (windows_thread::)(void*)' does not match 'DWORD (*)(void*)'| 
C:\windows_thread_2\windows_thread_2.cpp||In member function 'DWORD windows_thread::Thread_no_1(void*)':| 
C:\windows_thread_2\windows_thread_2.cpp|70|warning: deprecated conversion from string constant to 'char*'| 
||=== Build finished: 1 errors, 1 warnings ===| 

Heres le code.

#include <windows.h> 
//#include <strsafe.h> 
#include <stdio.h> 

#define BUF_SIZE 255 

class windows_thread 
{ 
//------------------------------------------------------------------- 
// A function to Display the message indicating in which tread we are 
//------------------------------------------------------------------- 
    public: 

     windows_thread(){} 
     ~windows_thread(){} 
     void thread() 
     { 
      int Data_Of_Thread_1 = 1;   // Data of Thread 1 
      HANDLE Handle_Of_Thread_1 = 0;  // variable to hold handle of Thread 1 

      HANDLE Array_Of_Thread_Handles[1]; // Aray to store thread handles 

    // Create thread 1. 
      Handle_Of_Thread_1 = CreateThread(NULL, 0, Thread_no_1, &Data_Of_Thread_1, 0, NULL); 
      if (Handle_Of_Thread_1 == NULL) ExitProcess(Data_Of_Thread_1); 

    // Store Thread handles in Array of Thread Handles as per the requirement of WaitForMultipleObjects() 
      Array_Of_Thread_Handles[0] = Handle_Of_Thread_1; 


    // Wait until all threads have terminated. 
      WaitForMultipleObjects(1, Array_Of_Thread_Handles, TRUE, INFINITE); 

      printf("Since All threads executed lets close their handles \n"); 

    // Close all thread handles upon completion. 
      CloseHandle(Handle_Of_Thread_1); 
     } 
     void DisplayMessage (HANDLE hScreen, char *ThreadName, int Data, int Count) 
     { 
      TCHAR msgBuf[BUF_SIZE]; 
      size_t cchStringSize; 
      DWORD dwChars; 

    // Print message using thread-safe functions. 
    //StringCchPrintf(msgBuf, BUF_SIZE, TEXT("Executing iteration %02d of %s having data = %02d \n"), Count, ThreadName, Data); 
    //StringCchLength(msgBuf, BUF_SIZE, &cchStringSize); 
      WriteConsole(hScreen, msgBuf, cchStringSize, &dwChars, NULL); 
      Sleep(1000); 
     } 

//------------------------------------------- 
// A function that represents Thread number 1 
//------------------------------------------- 
     DWORD WINAPI Thread_no_1(LPVOID lpParam) 
     { 
      int  Data = 0; 
      int  count = 0; 
      HANDLE hStdout = NULL; 

    // Get Handle To screen. Else how will we print? 
      if((hStdout = GetStdHandle(STD_OUTPUT_HANDLE)) == INVALID_HANDLE_VALUE) 
       return 1; 

    // Cast the parameter to the correct data type passed by callee i.e main() in our case. 
      Data = *((int*)lpParam); 

      for (count = 0; count <= 4; count++) 
      { 
       DisplayMessage (hStdout, "Thread_no_1", Data, count); 
      } 

      return 0; 
     } 
}; 
int main() 
{ 
    windows_thread threading; 
    threading.thread(); 

    return 0; 
} 

Je modifié le code en fonction de la réponse, s'il vous plaît le modifier si vous pouvez résoudre cette erreur. line 78 error: no matching function for call to 'windows_thread::Thread_no_1()'|

#include <windows.h> 
//#include <strsafe.h> 
#include <stdio.h> 

#define BUF_SIZE 255 

class windows_thread 
{ 
//------------------------------------------------------------------- 
// A function to Display the message indicating in which tread we are 
//------------------------------------------------------------------- 
    public: 

     windows_thread(){} 
     ~windows_thread(){} 
     void thread() 
     { 
      int Data_Of_Thread_1 = 1;   // Data of Thread 1 
      HANDLE Handle_Of_Thread_1 = 0;  // variable to hold handle of Thread 1 

      HANDLE Array_Of_Thread_Handles[1]; // Aray to store thread handles 

    // Create thread 1. 
      Handle_Of_Thread_1 = CreateThread(NULL, 0, Wrap_Thread_no_1, &Data_Of_Thread_1, 0, NULL); 
      if (Handle_Of_Thread_1 == NULL) ExitProcess(Data_Of_Thread_1); 

    // Store Thread handles in Array of Thread Handles as per the requirement of WaitForMultipleObjects() 
      Array_Of_Thread_Handles[0] = Handle_Of_Thread_1; 


    // Wait until all threads have terminated. 
      WaitForMultipleObjects(1, Array_Of_Thread_Handles, TRUE, INFINITE); 

      printf("Since All threads executed lets close their handles \n"); 

    // Close all thread handles upon completion. 
      CloseHandle(Handle_Of_Thread_1); 
     } 
     void DisplayMessage (HANDLE hScreen, char *ThreadName, int Data, int Count) 
     { 
      TCHAR msgBuf[BUF_SIZE]; 
      size_t cchStringSize; 
      DWORD dwChars; 

    // Print message using thread-safe functions. 
    //StringCchPrintf(msgBuf, BUF_SIZE, TEXT("Executing iteration %02d of %s having data = %02d \n"), Count, ThreadName, Data); 
    //StringCchLength(msgBuf, BUF_SIZE, &cchStringSize); 
      WriteConsole(hScreen, msgBuf, cchStringSize, &dwChars, NULL); 
      Sleep(1000); 
     } 

//------------------------------------------- 
// A function that represents Thread number 1 
//------------------------------------------- 
     DWORD WINAPI Thread_no_1(LPVOID lpParam) 
     { 
      int  Data = 0; 
      int  count = 0; 
      HANDLE hStdout = NULL; 

    // Get Handle To screen. Else how will we print? 
      if((hStdout = GetStdHandle(STD_OUTPUT_HANDLE)) == INVALID_HANDLE_VALUE) 
       return 1; 

    // Cast the parameter to the correct data type passed by callee i.e main() in our case. 
      Data = *((int*)lpParam); 

      for (count = 0; count <= 1; count++) 
      { 
       //DisplayMessage (hStdout, "Thread_no_1", Data, count); 
      } 

      return 0; 
     } 
     static DWORD WINAPI Wrap_Thread_no_1(LPVOID lpParam) 
     { 
      windows_thread *self = reinterpret_cast<windows_thread*>(lpParam); 
      self->Thread_no_1(); 
     } 
}; 
int main() 
{ 
    windows_thread threading; 
    threading.thread(); 

    return 0; 
} 

Répondre

4

Un thread doit être une "fonction simple", pas un appel à une fonction membre non statique d'une classe - ceux-ci nécessitent un argument "caché" supplémentaire pour le "this-pointeur".

Puisque votre code que vous avez jusqu'ici n'utilise aucune variable de membre [autant que je peux voir], la solution facile est de faire la fonction static. Si vous souhaitez utiliser des variables membres ou des fonctions membres de votre classe, vous devez avoir une fonction statique et passer l'objet (this) comme (partie de) l'argument du thread, puis utiliser un reinterpret_cast<windows_thread*>(arg); pour le reconvertir.

Quelque chose le long de ces lignes:

... 
    Handle_Of_Thread_1 = CreateThread(NULL, 0, Wrap_Thread_no_1, this, 0, NULL); 

... 

    static DWORD WINAPI Wrap_Thread_no_1(LPVOID lpParam) 
    { 
      windows_thread *self = reinterpret_cast<windows_thread*>(lpParam); 
      self->Thread_no_1(); 
    } 

J'ai enlevé votre argument original. En supposant que le thread n'exécute qu'un seul thread par objet, vous pouvez en faire une variable membre. Si vous avez besoin de plusieurs threads avec des paramètres individuels, alors vous devez faire le passé en paramètre un struct ou class et reinterpret_cast à cela, et stocker le pointeur this dans le cadre de cette struct ou class [qui peut alors windows_thread* ne sera donc pas besoin d'un casting].

+0

"passe l'objet (this) comme (partie de) l'argument au thread" Quel argument cependant? 'reinterpret_cast (arg);' Pourriez-vous donner un exemple? – pandoragami

+0

Voir la modification dans la réponse originale. –

+0

Merci Mats, je pense que j'ai édité mon code correctement sinon s'il vous plaît regarder mon message et le réparer. J'ai eu une erreur sur la ligne 78. merci pour l'instant. – pandoragami

3

Vous essayez de passer un pointer-to-member au fil, qui n'est pas la même chose qu'un pointeur brut ici. Il nécessite un objet à y attacher.

Handle_Of_Thread_1 = CreateThread(NULL, 0, Thread_no_1, &Data_Of_Thread_1, 0, NULL); 

Faire la fonction static en changeant ceci:

DWORD WINAPI Thread_no_1(LPVOID lpParam) 

à ceci:

static DWORD WINAPI Thread_no_1(LPVOID lpParam) 

... qui indique (correctement) que cette fonction n'a pas besoin this.

+1

L'approche habituelle consiste à passer une instance de l'objet en tant qu'argument 'LPVOID' à un rappel global/statique. –

+0

@Stephen Lin. Pourriez-vous poster un exemple de cela s'il vous plaît? – pandoragami

+0

@lost_with_coding qui ne s'applique pas ici, puisque les données que vous transmettez sont des 'int' locaux. Voir ma modification. –

Questions connexes