LPTHREAD_START_ROUTINE / array of classes

I wrote some test code like this which compiled and worked fine ...

void threadtest()
{
  HANDLE hThrd;
  DWORD threadId;
  int i;

  for (i = 0;i < 5;i++)
  {
    hThrd = CreateThread(
      NULL,
      0,
      ThreadFunc,
      (LPVOID)i,
      0,
      &threadId );
  }
  // more stuff
}

DWORD WINAPI ThreadFunc(LPVOID n)
{
  // stuff
  return 0;
}

      

Then I wanted to change the code to put ThreadFunc inside a class and then declare an array of those classes. I thought the code should look like this:

class thread_type
{

  public:

  DWORD WINAPI ThreadFunc(LPVOID n)
  {
    // stuff
    return 0;
  }
};

void threadtest()
{
  HANDLE hThrd;
  DWORD threadId;
  int i;
  thread_type *slave;

  slave = new thread_type[5];

  for (i = 0;i < 5;i++)
  {
    hThrd = CreateThread(
    NULL,
    0,
    slave[i].ThreadFunc,
    (LPVOID)i,
    0,
    &threadId );
  }
  // more stuff
}

      

Unfortunately the compiler is complaining about the subordinate line [i] .ThreadFunc, I think I might need some special casting, but all the permutations I'm trying to use with "::" and "&". seem to fail (I'm pretty new to C ++). The actual code has some additional complications that I have not included for clarity, but I think they are irrelevant.

+2


source to share


2 answers


The following explains the difference between a function pointer and a C ++ FAQ Lite member function pointer . See Section 33.2 for an explanation of why what you are doing is a bad idea.



+1


source


The first problem with the code is that the test class is not a descendant of thread_type. Somehow you need to specify the base class. Second, if you are passing a pointer to a function, it should not be of type thiscall. This is usually the solution:

struct thread
{
  virtual void
  run() = 0;

  static thread_func(void* param)
  {
    thread* pThread = (thread*)param;
    thread->run();
  }
}


struct worker : public thread
{
  void
  run()
  {
    (.. code for the thread...)
  }
}

void threadtest()
{
  HANDLE hThrd;
  DWORD threadId;
  int i;
  thread *slave;

  slave = new thread_type[5];
  slave[0] = new worker;
  slave[1] = new worker;
  slave[2] = new worker;
  slave[3] = new worker;
  slave[4] = new worker;

  for (i = 0;i < 5;i++)
  {
    hThrd = CreateThread(
    NULL,
    0,
    &thread::thread_func,
    (LPVOID)slave[i],
    0,
    &threadId );
  }
  // more stuff
}

      



Note that this might just be a reflection, I couldn't compile now because I don't have anything like that, but the logic should be like this.

+4


source







All Articles