// Listing 2 - thread2.h
#include <memory> // for auto_ptr<>
#include <winbase.h> // for CreateThread and macros
template <typename Object, typename MemberFunc, typename Param>
class ThreadableMember
{
private:
Object& _instance;
MemberFunc _member;
struct ThrdArg
{
Object *object;
MemberFunc memberFunc;
Param param;
ThrdArg (Object& o, MemberFunc m, const Param& p)
: object(&o), memberFunc(m), param(p) {}
};
static DWORD WINAPI ThreadFunc (LPVOID v)
{
std::auto_ptr<ThrdArg> arg(reinterpret_cast<ThrdArg*>(v));
return ((arg->object)->*(arg->memberFunc))(arg->param);
}
public:
ThreadableMember(Object& instance, MemberFunc member)
: _instance(instance), _member(member) {}
void run(const Param& param, HANDLE* handle=0, DWORD* id=0)
{
DWORD threadId = -1;
ThrdArg *thrdArg=new ThrdArg(_instance,_member,param);
// replace CreateThread if your compiler has a function
// to initialize a thread-safe C runtime library
HANDLE result =
CreateThread(
0,
0,
&ThreadFunc,
thrdArg,
0,
&threadId);
if (result != 0)
{
if (handle) *handle = result;
if (id) *id = threadId;
}
else
{
delete thrdArg;
throw std::runtime_error("CreateThread failed.");
}
}
};
// provided to support automatic detection of types
template <typename Object, typename MemberFunc, typename Param>
inline void runInThread(Object& instance,
MemberFunc member,
const Param& param,
HANDLE* handle=0,
DWORD* id=0)
{
ThreadableMember<Object,MemberFunc,Param> m(instance,member);
m.run(param,handle,id);
}