I tried to create a thread inside of a class and I got an error. I'm just wondering if there is way around this or must I use threads within int main()
only?
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 the 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;
}
I edited the code based on the answer, please edit it if you can solve this error.
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;
}
A thread must be a "plain function", not a call to a non-static member function of a class - these require an extra "hidden" argument for the "this-pointer".
Since your code that you have so far doesn't use any member variables [as far as I can see], the easy solution is to make the function static
.
If you want to use member variables or member functions of your class, then you will need to have a static function and pass the object (this
) as (part of) the argument to the thread, and then use a reinterpret_cast<windows_thread*>(arg);
to convert it back.
Something along these lines:
...
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();
}
I have removed your original argument. Assuming the thread is running only one thread per object, you could make it a member variable. If you need multiple threads with individual parameters, then you need to make the passed in parameter a struct
or class
, and reinterpret_cast
to that, and store the this
pointer as part of that struct
or class
[which can then be windows_thread*
so won't need a cast].