Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. C / C++ / MFC
  4. Multithreading using AfxBeginThread

Multithreading using AfxBeginThread

Scheduled Pinned Locked Moved C / C++ / MFC
csharpvisual-studiohelp
14 Posts 4 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • K kartikthakre

    I am creating thread using AfxBeginThread in Visual Studio 2005 and the first parameter of this function is function pointer so i am passing member function pointer of that class but it gives error i.e. my code is: AfxBeginThread( &CMultithreadingInDialogDlg::MyThreadProc, GetSafeHwnd() ); in which MyThreadProc is member function. and the error is error C2665: 'AfxBeginThread' : none of the 2 overloads could convert all the argument types. but it is working if i am passing function pointer of any static function or global function thanks in advance.

    D Offline
    D Offline
    David Crow
    wrote on last edited by
    #2

    Is MyThreadProc() a static member of CMultithreadingInDialogDlg?

    "One man's wage rise is another man's price increase." - Harold Wilson

    "Fireproof doesn't mean the fire will never come. It means when the fire comes that you will be able to withstand it." - Michael Simmons

    "Man who follows car will be exhausted." - Confucius

    K 1 Reply Last reply
    0
    • K kartikthakre

      I am creating thread using AfxBeginThread in Visual Studio 2005 and the first parameter of this function is function pointer so i am passing member function pointer of that class but it gives error i.e. my code is: AfxBeginThread( &CMultithreadingInDialogDlg::MyThreadProc, GetSafeHwnd() ); in which MyThreadProc is member function. and the error is error C2665: 'AfxBeginThread' : none of the 2 overloads could convert all the argument types. but it is working if i am passing function pointer of any static function or global function thanks in advance.

      E Offline
      E Offline
      Eugen Podsypalnikov
      wrote on last edited by
      #3

      kartikthakre wrote:

      but it is working if i am passing function pointer of any static function or global function

      That is also the "classical" way to pass - for example - a private static function of a dialog... :)

      // .h
      ...
      class CYourDialog : public CDialog
      {
      bool m_bWorking;
      CWinThread* m_pcThread;
      static DWORD WINAPI ThreadProc(CYourDialog*);
      ...
      public:
      CYourDialog(CWnd* pcParent = NULL);
      ~CYourDialog();
      ...
      void On();
      void Off();
      ...
      };
      // .cpp
      ...
      CYourDialog::CYourDialog(CWnd* pcParent /*= NULL*/)
      : CDialog(CYourDialog::IDD, pcParent),
      m_bWorking(false),
      m_pcThread(NULL)
      {
      ...
      }
      CYourDialog::~CYourDialog()
      {
      Off();
      }
      CYourDialog::On()
      {
      if (!m_bWorking && !m_pcThread) {
      m_bWorking = true;
      m_pcThread = AfxBeginThread(ThreadProc, this);
      }
      }
      CYourDialog::Off()
      {
      if (m_bWorking && m_pcThread) {
      m_bWorking = false;
      WaitForSingleObject(m_pcThread->m_hThread, INFINITE);
      m_pcThread = NULL;
      }
      }
      DWORD WINAPI CYourDialog::ThreadProc(CYourDialog* pcDlg)
      {
      while (pcDlg && pcDlg->m_bWorking) {
      // Do something
      Sleep(1);
      }
      return 0;
      }

      virtual void BeHappy() = 0;

      modified on Thursday, April 1, 2010 2:42 AM

      R D K 3 Replies Last reply
      0
      • E Eugen Podsypalnikov

        kartikthakre wrote:

        but it is working if i am passing function pointer of any static function or global function

        That is also the "classical" way to pass - for example - a private static function of a dialog... :)

        // .h
        ...
        class CYourDialog : public CDialog
        {
        bool m_bWorking;
        CWinThread* m_pcThread;
        static DWORD WINAPI ThreadProc(CYourDialog*);
        ...
        public:
        CYourDialog(CWnd* pcParent = NULL);
        ~CYourDialog();
        ...
        void On();
        void Off();
        ...
        };
        // .cpp
        ...
        CYourDialog::CYourDialog(CWnd* pcParent /*= NULL*/)
        : CDialog(CYourDialog::IDD, pcParent),
        m_bWorking(false),
        m_pcThread(NULL)
        {
        ...
        }
        CYourDialog::~CYourDialog()
        {
        Off();
        }
        CYourDialog::On()
        {
        if (!m_bWorking && !m_pcThread) {
        m_bWorking = true;
        m_pcThread = AfxBeginThread(ThreadProc, this);
        }
        }
        CYourDialog::Off()
        {
        if (m_bWorking && m_pcThread) {
        m_bWorking = false;
        WaitForSingleObject(m_pcThread->m_hThread, INFINITE);
        m_pcThread = NULL;
        }
        }
        DWORD WINAPI CYourDialog::ThreadProc(CYourDialog* pcDlg)
        {
        while (pcDlg && pcDlg->m_bWorking) {
        // Do something
        Sleep(1);
        }
        return 0;
        }

        virtual void BeHappy() = 0;

        modified on Thursday, April 1, 2010 2:42 AM

        R Offline
        R Offline
        Roger Stoltz
        wrote on last edited by
        #4

        Perhaps it's just a typo, but if not you should be aware of the following: There's a big risk the thread will never exit as you've failed to declare the m_bWorking variable as volatile. It depends on your optimization settings. The compiler may choose to hold the variable in a register in the while-loop, not reading it from its actual memory location since it's not being modified in the while-loop. Declaring it as volatile will tell the compiler that the variable must be read from its memory location and cannot be optimized into a register.

        "It's supposed to be hard, otherwise anybody could do it!" - selfquote
        "High speed never compensates for wrong direction!" - unknown

        E 1 Reply Last reply
        0
        • R Roger Stoltz

          Perhaps it's just a typo, but if not you should be aware of the following: There's a big risk the thread will never exit as you've failed to declare the m_bWorking variable as volatile. It depends on your optimization settings. The compiler may choose to hold the variable in a register in the while-loop, not reading it from its actual memory location since it's not being modified in the while-loop. Declaring it as volatile will tell the compiler that the variable must be read from its memory location and cannot be optimized into a register.

          "It's supposed to be hard, otherwise anybody could do it!" - selfquote
          "High speed never compensates for wrong direction!" - unknown

          E Offline
          E Offline
          Eugen Podsypalnikov
          wrote on last edited by
          #5

          Wow, I did not know it ! Thank you very much, Roger ! :) :thumbsup: As possible "workaround" could be also the usage of a limitation function:

          bool CYourDialog::IsWorking() {
          return m_bWorking;
          }

          virtual void BeHappy() = 0;

          R 1 Reply Last reply
          0
          • E Eugen Podsypalnikov

            Wow, I did not know it ! Thank you very much, Roger ! :) :thumbsup: As possible "workaround" could be also the usage of a limitation function:

            bool CYourDialog::IsWorking() {
            return m_bWorking;
            }

            virtual void BeHappy() = 0;

            R Offline
            R Offline
            Roger Stoltz
            wrote on last edited by
            #6

            Eugen Podsypalnikov wrote:

            Wow, I did not know it ! Thank you very much, Roger !

            :) You're most welcome.

            Eugen Podsypalnikov wrote:

            As possible "workaround" could be also the usage of a limitation function:

            bool CYourDialog::IsWorking() {
            return m_bWorking;
            }

            Naah, I wouldn't count on that. This also depends on your optimization settings... ;) There's a compiler switch that tells the compiler to expand "any suitable" function as inline, which would generate the same code as if you would have referenced the variable directly even though you haven't declared the function explicitly as inline. Then you would be back to square one, with the possibility that the variable could be optimized into a register.

            "It's supposed to be hard, otherwise anybody could do it!" - selfquote
            "High speed never compensates for wrong direction!" - unknown

            E 1 Reply Last reply
            0
            • R Roger Stoltz

              Eugen Podsypalnikov wrote:

              Wow, I did not know it ! Thank you very much, Roger !

              :) You're most welcome.

              Eugen Podsypalnikov wrote:

              As possible "workaround" could be also the usage of a limitation function:

              bool CYourDialog::IsWorking() {
              return m_bWorking;
              }

              Naah, I wouldn't count on that. This also depends on your optimization settings... ;) There's a compiler switch that tells the compiler to expand "any suitable" function as inline, which would generate the same code as if you would have referenced the variable directly even though you haven't declared the function explicitly as inline. Then you would be back to square one, with the possibility that the variable could be optimized into a register.

              "It's supposed to be hard, otherwise anybody could do it!" - selfquote
              "High speed never compensates for wrong direction!" - unknown

              E Offline
              E Offline
              Eugen Podsypalnikov
              wrote on last edited by
              #7

              Yes, saved... :) Thank you - for the both explanations, Roger !

              virtual void BeHappy() = 0;

              1 Reply Last reply
              0
              • E Eugen Podsypalnikov

                kartikthakre wrote:

                but it is working if i am passing function pointer of any static function or global function

                That is also the "classical" way to pass - for example - a private static function of a dialog... :)

                // .h
                ...
                class CYourDialog : public CDialog
                {
                bool m_bWorking;
                CWinThread* m_pcThread;
                static DWORD WINAPI ThreadProc(CYourDialog*);
                ...
                public:
                CYourDialog(CWnd* pcParent = NULL);
                ~CYourDialog();
                ...
                void On();
                void Off();
                ...
                };
                // .cpp
                ...
                CYourDialog::CYourDialog(CWnd* pcParent /*= NULL*/)
                : CDialog(CYourDialog::IDD, pcParent),
                m_bWorking(false),
                m_pcThread(NULL)
                {
                ...
                }
                CYourDialog::~CYourDialog()
                {
                Off();
                }
                CYourDialog::On()
                {
                if (!m_bWorking && !m_pcThread) {
                m_bWorking = true;
                m_pcThread = AfxBeginThread(ThreadProc, this);
                }
                }
                CYourDialog::Off()
                {
                if (m_bWorking && m_pcThread) {
                m_bWorking = false;
                WaitForSingleObject(m_pcThread->m_hThread, INFINITE);
                m_pcThread = NULL;
                }
                }
                DWORD WINAPI CYourDialog::ThreadProc(CYourDialog* pcDlg)
                {
                while (pcDlg && pcDlg->m_bWorking) {
                // Do something
                Sleep(1);
                }
                return 0;
                }

                virtual void BeHappy() = 0;

                modified on Thursday, April 1, 2010 2:42 AM

                D Offline
                D Offline
                David Crow
                wrote on last edited by
                #8

                Eugen Podsypalnikov wrote:

                DWORD WINAPI CYourDialog::ThreadProc(CYourDialog* pcDlg)

                Shouldn't this be:

                UINT CYourDialog::ThreadProc( LPVOID pcDlg )

                "One man's wage rise is another man's price increase." - Harold Wilson

                "Fireproof doesn't mean the fire will never come. It means when the fire comes that you will be able to withstand it." - Michael Simmons

                "Man who follows car will be exhausted." - Confucius

                E 1 Reply Last reply
                0
                • D David Crow

                  Eugen Podsypalnikov wrote:

                  DWORD WINAPI CYourDialog::ThreadProc(CYourDialog* pcDlg)

                  Shouldn't this be:

                  UINT CYourDialog::ThreadProc( LPVOID pcDlg )

                  "One man's wage rise is another man's price increase." - Harold Wilson

                  "Fireproof doesn't mean the fire will never come. It means when the fire comes that you will be able to withstand it." - Michael Simmons

                  "Man who follows car will be exhausted." - Confucius

                  E Offline
                  E Offline
                  Eugen Podsypalnikov
                  wrote on last edited by
                  #9

                  Yes, of course :) You could use my declaration too and pass it by the casting (AFX_THREADPROC) , so you can use its parameter pcDlg without casting... :)

                  virtual void BeHappy() = 0;

                  1 Reply Last reply
                  0
                  • E Eugen Podsypalnikov

                    kartikthakre wrote:

                    but it is working if i am passing function pointer of any static function or global function

                    That is also the "classical" way to pass - for example - a private static function of a dialog... :)

                    // .h
                    ...
                    class CYourDialog : public CDialog
                    {
                    bool m_bWorking;
                    CWinThread* m_pcThread;
                    static DWORD WINAPI ThreadProc(CYourDialog*);
                    ...
                    public:
                    CYourDialog(CWnd* pcParent = NULL);
                    ~CYourDialog();
                    ...
                    void On();
                    void Off();
                    ...
                    };
                    // .cpp
                    ...
                    CYourDialog::CYourDialog(CWnd* pcParent /*= NULL*/)
                    : CDialog(CYourDialog::IDD, pcParent),
                    m_bWorking(false),
                    m_pcThread(NULL)
                    {
                    ...
                    }
                    CYourDialog::~CYourDialog()
                    {
                    Off();
                    }
                    CYourDialog::On()
                    {
                    if (!m_bWorking && !m_pcThread) {
                    m_bWorking = true;
                    m_pcThread = AfxBeginThread(ThreadProc, this);
                    }
                    }
                    CYourDialog::Off()
                    {
                    if (m_bWorking && m_pcThread) {
                    m_bWorking = false;
                    WaitForSingleObject(m_pcThread->m_hThread, INFINITE);
                    m_pcThread = NULL;
                    }
                    }
                    DWORD WINAPI CYourDialog::ThreadProc(CYourDialog* pcDlg)
                    {
                    while (pcDlg && pcDlg->m_bWorking) {
                    // Do something
                    Sleep(1);
                    }
                    return 0;
                    }

                    virtual void BeHappy() = 0;

                    modified on Thursday, April 1, 2010 2:42 AM

                    K Offline
                    K Offline
                    kartikthakre
                    wrote on last edited by
                    #10

                    Thanks for reply, But i already written that it is working for static and global function. What i want is that it is work for member function. I am waiting for reply thanks

                    D 1 Reply Last reply
                    0
                    • D David Crow

                      Is MyThreadProc() a static member of CMultithreadingInDialogDlg?

                      "One man's wage rise is another man's price increase." - Harold Wilson

                      "Fireproof doesn't mean the fire will never come. It means when the fire comes that you will be able to withstand it." - Michael Simmons

                      "Man who follows car will be exhausted." - Confucius

                      K Offline
                      K Offline
                      kartikthakre
                      wrote on last edited by
                      #11

                      MyThreadProc is not a static function, it is simple member function.

                      D 1 Reply Last reply
                      0
                      • K kartikthakre

                        MyThreadProc is not a static function, it is simple member function.

                        D Offline
                        D Offline
                        David Crow
                        wrote on last edited by
                        #12

                        Which means it cannot be used an argument to AfxBeginThread().

                        "One man's wage rise is another man's price increase." - Harold Wilson

                        "Fireproof doesn't mean the fire will never come. It means when the fire comes that you will be able to withstand it." - Michael Simmons

                        "Man who follows car will be exhausted." - Confucius

                        1 Reply Last reply
                        0
                        • K kartikthakre

                          Thanks for reply, But i already written that it is working for static and global function. What i want is that it is work for member function. I am waiting for reply thanks

                          D Offline
                          D Offline
                          David Crow
                          wrote on last edited by
                          #13

                          kartikthakre wrote:

                          What i want is that it is work for member function.

                          You can't do it directly. What you'll have to do is:

                          void CMyDlg::ThreadProc( void )
                          {
                          ...
                          }

                          UINT ThreadProc( LPVOID lpParam )
                          {
                          CMyDlg *pDlg = (CMyDlg *) lpParam;

                          pDlg->ThreadProc();
                          
                          return 0;
                          

                          }

                          static UINT CMyDlg::ThreadProc( LPVOID lpParam )
                          {
                          CMyDlg *pDlg = (CMyDlg *) lpParam;

                          pDlg->ThreadProc();
                          
                          return 0;
                          

                          }

                          AfxBeginThread(ThreadProc, this); // static member
                          AfxBeginThread(::ThreadProc, this); // global

                          "One man's wage rise is another man's price increase." - Harold Wilson

                          "Fireproof doesn't mean the fire will never come. It means when the fire comes that you will be able to withstand it." - Michael Simmons

                          "Man who follows car will be exhausted." - Confucius

                          K 1 Reply Last reply
                          0
                          • D David Crow

                            kartikthakre wrote:

                            What i want is that it is work for member function.

                            You can't do it directly. What you'll have to do is:

                            void CMyDlg::ThreadProc( void )
                            {
                            ...
                            }

                            UINT ThreadProc( LPVOID lpParam )
                            {
                            CMyDlg *pDlg = (CMyDlg *) lpParam;

                            pDlg->ThreadProc();
                            
                            return 0;
                            

                            }

                            static UINT CMyDlg::ThreadProc( LPVOID lpParam )
                            {
                            CMyDlg *pDlg = (CMyDlg *) lpParam;

                            pDlg->ThreadProc();
                            
                            return 0;
                            

                            }

                            AfxBeginThread(ThreadProc, this); // static member
                            AfxBeginThread(::ThreadProc, this); // global

                            "One man's wage rise is another man's price increase." - Harold Wilson

                            "Fireproof doesn't mean the fire will never come. It means when the fire comes that you will be able to withstand it." - Michael Simmons

                            "Man who follows car will be exhausted." - Confucius

                            K Offline
                            K Offline
                            kartikthakre
                            wrote on last edited by
                            #14

                            but what is the region, so that member function pointer is not pass to AfxBeginThread.

                            1 Reply Last reply
                            0
                            Reply
                            • Reply as topic
                            Log in to reply
                            • Oldest to Newest
                            • Newest to Oldest
                            • Most Votes


                            • Login

                            • Don't have an account? Register

                            • Login or register to search.
                            • First post
                              Last post
                            0
                            • Categories
                            • Recent
                            • Tags
                            • Popular
                            • World
                            • Users
                            • Groups