create thread in class
You have to define the thread function DWORD WINAPI ListenThread (LPVOID WorkContext);
as a static
function of the class:
class MyClass
{
public:
static DWORD WINAPI ListenThread (LPVOID WorkContext);
}
It is not possible to call a member function without an instance of an object. In your case this
is only a parameter that will be passed as WorkContext
in your now static function ListenThread
.
As another solution, you could also consider using C++11
std::bind
so as to create a function object from that you would pass to CreateThread.That would go something like this - sorry I have not windows so as to check if this compiles - but it gives you the idea:
bool MyClass::CreateListenThreads()
{
using std::placeholders;
std::function <void (void*)> threadFunction = std::bind(&MyClass::ListenThread, *this, _1);
m_ListenThr = CreateThread(NULL, 0, threadFunction,(void*)this, 0,&dwThreadId);
}
but that would sort of use the reference to this twice: as the instance of the class to call the function on, and as a parameter LPVOID WorkContext. Maybe it's awkward in this present case.
Create thread inside class with function from same class
foo_func
is a (non-static
) member function, and it needs an instance of foo
on which to operate. This instance must be provided to the thread constructor. If you refer to the std::thread::thread reference page it explains what code is executed in the new thread. The relevant point is that which refers to f
being a pointer to member function:
- If
f
is pointer to a member function of classT
, then it is called. The return value is ignored. Effectively, the following code is executed:
(t1.*f)(t2, ..., tN)
if the type oft1
is eitherT
, reference toT
or reference to type derived fromT
.((*t1).*f)(t2, ..., tN)
otherwise.
so it is clear that the instance is required.
Change to:
for(...) some_threads.push_back(std::thread(&foo::foo_func, this));
Simple example:
#include <iostream>
#include <thread>
#include <vector>
class foo
{
public:
void make_foo_func_threads()
{
for (int i = 0; i < 5; ++i)
some_threads.push_back(std::thread(&foo::foo_func, this));
for (auto& t: some_threads) t.join();
}
private:
void foo_func() { std::cout << "Hello\n"; }
std::vector<std::thread> some_threads;
};
int main()
{
foo f;
f.make_foo_func_threads();
}
WINAPI: Create new thread on class member function - incompatable parameter type
Answer courtesy of Hans Passant. See Comments on question:
The trampoline is missing WINAPI in its definition.
Create thread is not accepting the member function
At lost I got it, the very fact is, in CreateThread if you pass the socket then there is no trouble. Because CreateThread is taking care of that socket. But if you pass as an object which is having that socket, then CreateThread is not taking care of the socket, and it is ends up in invalid socket in the new thread.
The successed code below
SOCKET s=socket(....);
bind(s,...);
listen(s,...);
SOCKET temp=accept(s,(sockaddr *)&addrNew,&size);
DWORD threadId;
HANDLE thread=CreateThread(NULL,0,&MyThreadFunction,(LPVOID)(temp),0,&threadId);
Start thread with member function
#include <thread>
#include <iostream>
class bar {
public:
void foo() {
std::cout << "hello from member function" << std::endl;
}
};
int main()
{
std::thread t(&bar::foo, bar());
t.join();
}
EDIT:
Accounting your edit, you have to do it like this:
std::thread spawn() {
return std::thread(&blub::test, this);
}
UPDATE: I want to explain some more points, some of them have also been discussed in the comments.
The syntax described above is defined in terms of the INVOKE definition (§20.8.2.1):
Define INVOKE (f, t1, t2, ..., tN) as follows:
- (t1.*f)(t2, ..., tN) when f is a pointer to a member function of a class T and t1 is an object of type T or a reference to an object of
type T or a reference to an object of a type derived from T;- ((*t1).*f)(t2, ..., tN) when f is a pointer to a member function of a class T and t1 is not one of the types described in the previous
item;- t1.*f when N == 1 and f is a pointer to member data of a class T and t 1 is an object of type T or a
reference to an object of type T or a reference to an object of a
type derived from T;- (*t1).*f when N == 1 and f is a pointer to member data of a class T and t 1 is not one of the types described in the previous item;
- f(t1, t2, ..., tN) in all other cases.
Another general fact which I want to point out is that by default the thread constructor will copy all arguments passed to it. The reason for this is that the arguments may need to outlive the calling thread, copying the arguments guarantees that. Instead, if you want to really pass a reference, you can use a std::reference_wrapper
created by std::ref
.
std::thread (foo, std::ref(arg1));
By doing this, you are promising that you will take care of guaranteeing that the arguments will still exist when the thread operates on them.
Note that all the things mentioned above can also be applied to std::async
and std::bind
.
Related Topics
Can the Use of C++11's 'Auto' Improve Performance
Why Do Some People Use Swap for Move Assignments
Why Does the Enhanced Gcc 6 Optimizer Break Practical C++ Code
Lambda Expressions as Class Template Parameters
Sse, Intrinsics, and Alignment
Inheritance or Composition: Rely on "Is-A" and "Has-A"
Std::To_String - More Than Instance of Overloaded Function Matches the Argument List
Do Class Functions/Variables Have to Be Declared Before Being Used
Avoiding the Tedium of Optional Parameters
C++ on X86-64: When Are Structs/Classes Passed and Returned in Registers
5 Years Later, Is There Something Better Than the "Fastest Possible C++ Delegates"
How to Overload the Operator++ in Two Different Ways for Postfix A++ and Prefix ++A
Where Do I Find the Definition of Size_T
Are C++ Templates Just MACros in Disguise
Will Casting Around Sockaddr_Storage and Sockaddr_In Break Strict Aliasing
(Partially) Specializing a Non-Type Template Parameter of Dependent Type