using threads with C++

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • arunmib
    New Member
    • May 2007
    • 104

    using threads with C++

    Hi all,
    Following is my program,

    My header file,
    Code:
     
    
    class Test
    {
       private:
            ........ some declarations......
        public:
           Test();
           ~Test();
    
         int AnotherFunc();
           
          //my thread function
          static DWORD WINAPI threadFunc(LPVOID);
    }
    my CPP file
    Code:
    int iGlobal = 0;
    
    Test::Test()
    {
       ......some processes and declarations....
       HANDLE hThrd = CreatThread(NULL, 0, threadFunc, NULL, 0, NULL);
       .........some other processes.......
       CloseHandle(hThrd);
    }
    
    int Test::AnotherFunc()
    {
      ........
      return 0;
    }
    
    DWORD WINAPI Test::threadFunc(LPVOID lpArgs)
    {
        iGlobal = 0;
        .....it does some processs......
        if(iGlobal == 1)
           AnotherFunc();
    
        return 0;
    }
    I am using borland C++ builder 6 and my OS is WinXP. When I build this project I get the error, "Use . or -> to call Test::AnotherFu nc()". I am not able to understand why this is happening ?

    If I try to declare iGlobal in my Test class, I get the error message "member Test::iGlobal cannot be used without an object".

    Can somebody help me with these two errors and explain these errors....
  • weaknessforcats
    Recognized Expert Expert
    • Mar 2007
    • 9214

    #2
    Your THREADPROC is a static function, as it should be.

    However, as a static function it can't call a class member function since there is no object. That is, the static function does not have a this pointer.

    What you should do is pass the this pointer to your THREADPROC as the LPVOID argument. Then the THTREADPPROC can typecast the LPVOID back to your class type and you can go from there. However, you can't do this in a constructor because the Test object is not yet initialized.

    Instead, have a Launch() method to call the CreateThread and an Execute() that can be called by the thread:

    [code=cpp]
    class Test
    {
    public:
    DWORD Launch();
    DWORD Execute();
    static DWORD WINAPI threadfunc(LPVO ID arg);

    };



    Test::Launch()
    {
    ......some processes and declarations... .
    HANDLE hThrd = CreatThread(NUL L, 0, threadFunc, this, 0, &hThrd);
    if (!hThrd)
    {
    //CreateThread failed. GetLastError()
    }
    .........some other processes...... .
    CloseHandle(hTh rd);
    }
    [/code]

    The threadfunc knows the the LPVOID is really a Test* so it is safe to typecast the LPVOID to a Test*:
    [code=cpp]
    DWORD WINAPI Test::threadfun c(LPVOID arg)
    {
    reinterpret_cas t<Test*> (arg)->Execute();
    return 0; //thread has completed
    }
    [/code]

    It is Test::Excute that contains the thread logic. This function should be called only by the THREADPROC. When it returns, the threadfunc returns and your thread is complete. This Test::Execute() is where you can WaitForSingleOb ject. Since Test::Execute() is a member function, it has the this pointer which means you can call any other class method from this function.

    In main() it looks like:

    [code=cpp]
    Test obj;

    DWORD rval = obj.Launch();
    //Thread is complete here
    [/code]

    Comment

    • arunmib
      New Member
      • May 2007
      • 104

      #3
      thanks weaknessforcats , that has made things clear for me.... :-)

      Comment

      Working...