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. Thread func

Thread func

Scheduled Pinned Locked Moved C / C++ / MFC
helptutorialquestioncareer
10 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.
  • C Offline
    C Offline
    CoY0te
    wrote on last edited by
    #1

    I want to use CreateThread() function, and i have created a ThreadFunc. The problem is, that i want this ThreadFunc to be placed within a calss (i don't want it to be a global function). member function is defined as follows: unsigned long __stdcall ThreadFunc(void * Parameter); And i try to do a conversion to: LPTHREAD_START_ROUTINE TS; Both: TS=ThreadFunc; And: TS=CMyDialog::ThreadFunc; Report as follows: error C2440: '=' : cannot convert from 'unsigned long (__stdcall CMyDialog::*)(void *)' to 'unsigned long (__stdcall *)(void *)' First conversion works when ThreadFunc is not a class member, but both fails when it is a class member. How to make this conversion? Railgun is like a Gilette Mach 3 - it does the job with one, easy stroke.

    T J 2 Replies Last reply
    0
    • C CoY0te

      I want to use CreateThread() function, and i have created a ThreadFunc. The problem is, that i want this ThreadFunc to be placed within a calss (i don't want it to be a global function). member function is defined as follows: unsigned long __stdcall ThreadFunc(void * Parameter); And i try to do a conversion to: LPTHREAD_START_ROUTINE TS; Both: TS=ThreadFunc; And: TS=CMyDialog::ThreadFunc; Report as follows: error C2440: '=' : cannot convert from 'unsigned long (__stdcall CMyDialog::*)(void *)' to 'unsigned long (__stdcall *)(void *)' First conversion works when ThreadFunc is not a class member, but both fails when it is a class member. How to make this conversion? Railgun is like a Gilette Mach 3 - it does the job with one, easy stroke.

      T Offline
      T Offline
      Tomasz Sowinski
      wrote on last edited by
      #2

      If you insist on member function, you must make it a static one. Also, if you use CreateThread, you may hit problems with C++ runtime. Use _beginthread[ex]; these functions call CreateThread for you. Tomasz Sowinski -- http://www.shooltz.com

      What is "scratch" and why can everything be made from it?

      1 Reply Last reply
      0
      • C CoY0te

        I want to use CreateThread() function, and i have created a ThreadFunc. The problem is, that i want this ThreadFunc to be placed within a calss (i don't want it to be a global function). member function is defined as follows: unsigned long __stdcall ThreadFunc(void * Parameter); And i try to do a conversion to: LPTHREAD_START_ROUTINE TS; Both: TS=ThreadFunc; And: TS=CMyDialog::ThreadFunc; Report as follows: error C2440: '=' : cannot convert from 'unsigned long (__stdcall CMyDialog::*)(void *)' to 'unsigned long (__stdcall *)(void *)' First conversion works when ThreadFunc is not a class member, but both fails when it is a class member. How to make this conversion? Railgun is like a Gilette Mach 3 - it does the job with one, easy stroke.

        J Offline
        J Offline
        Joao Vaz
        wrote on last edited by
        #3

        Adding to what Tomasz said, use only the _beginthreadex(do not use _beginthread or CreateThread) or AfxBeginThread in MFC, these 2 functions create the necessary TIB(Thread Information Block) that is necessary to the C/C++ runtime could correctly dispose and control the Thread specific data. Cheers, Joao Vaz And if your dream is to care for your family, to put food on the table, to provide them with an education and a good home, then maybe suffering through an endless, pointless, boring job will seem to have purpose. And you will realize how even a rock can change the world, simply by remaining obstinately stationary. - Shog9

        C 1 Reply Last reply
        0
        • J Joao Vaz

          Adding to what Tomasz said, use only the _beginthreadex(do not use _beginthread or CreateThread) or AfxBeginThread in MFC, these 2 functions create the necessary TIB(Thread Information Block) that is necessary to the C/C++ runtime could correctly dispose and control the Thread specific data. Cheers, Joao Vaz And if your dream is to care for your family, to put food on the table, to provide them with an education and a good home, then maybe suffering through an endless, pointless, boring job will seem to have purpose. And you will realize how even a rock can change the world, simply by remaining obstinately stationary. - Shog9

          C Offline
          C Offline
          CoY0te
          wrote on last edited by
          #4

          Thank you for an advise. Using static function was the key problem. Now it works fine. By the way - what kind of runtime problems may occur when using CreateThread? I've been using this one many times, and never had problems with managing threads. [ CoY0te ] Railgun is like a Gilette Mach 3 - it does the job with one, easy stroke.

          T D 2 Replies Last reply
          0
          • C CoY0te

            Thank you for an advise. Using static function was the key problem. Now it works fine. By the way - what kind of runtime problems may occur when using CreateThread? I've been using this one many times, and never had problems with managing threads. [ CoY0te ] Railgun is like a Gilette Mach 3 - it does the job with one, easy stroke.

            T Offline
            T Offline
            Tomasz Sowinski
            wrote on last edited by
            #5

            Check this article for discussion of CreateThread vs AfxBeginThread vs _beginthreadex: http://www.microsoft.com/msj/defaulttop.asp?page=/msj/archive/S39CD.htm[^] Heer's an interesting excerpt: Don't create threads with the C runtime functions beginthread or beginthreadex if the threads will access any MFC objects. The framework uses CWinThread to manage thread-specific data. You should use AfxBeginThread to start your threads (or call the CWinThread constructor and its CreateThread method). CWinThread::CreateThread eventually calls beginthreadex after taking care of some setup and synchronization Tomasz Sowinski -- http://www.shooltz.com

            What is "scratch" and why can everything be made from it?

            1 Reply Last reply
            0
            • C CoY0te

              Thank you for an advise. Using static function was the key problem. Now it works fine. By the way - what kind of runtime problems may occur when using CreateThread? I've been using this one many times, and never had problems with managing threads. [ CoY0te ] Railgun is like a Gilette Mach 3 - it does the job with one, easy stroke.

              D Offline
              D Offline
              Daniel Lohmann
              wrote on last edited by
              #6

              Even while thread functions follow the calling conventions of a standard C function and therfore have to be static functions, it is not impossible to create a thread directly in a member function. The key to do this is utilizing adapter objects, that translate the C-stylish callback into a call to a member function. This is explained in detail in the article Use member functions for C-style callbacks and threads - a general solution. Using the techiques described there, creating threads becomes real fun:

              #include "stdafx.h"
              #include "win_adapter.h" // This header file contains the "magic" stuff

              class Test
              {
              public:

              // Thread should be started in this function. 
              // Note that we can use \*any\* type for the single thread parameter
              virtual DWORD ThreadStart( LPCTSTR pszName )
              {
                  printf( "  Hello, I'm a Thread and my name is: %s\\n", pszName );
                  return 0;
              }
              

              };

              void main()
              {
              Test test;

              // Creating a thread that starts execution in a member function
              LPCTSTR pszThreadName = "Joe, the funny thread";
              HANDLE hThread = win::beginthreadex( &test, &Test::ThreadStart, pszThreadName );
              
              // Waiting for thread termination
              WaitForSingleObject( hThread, INFINITE );
              CloseHandle( hThread );
              

              }

              Of course this makes live and code a lot nicer, because you don't have to write all those static wrappers including ugly casts and so on. And the best thing is, that all you need to use it is to include one single header file! No CPP file to add to your project, no libs, no interface or class to derive from, no structural dependencies at all. :-D (Ehm, yes... I am a bit proud about this piece of code :-O ) -- Daniel Lohmann http://www.losoft.de (Hey, this page is worth looking! You can find some free and handy NT tools there :-D )

              T C 2 Replies Last reply
              0
              • D Daniel Lohmann

                Even while thread functions follow the calling conventions of a standard C function and therfore have to be static functions, it is not impossible to create a thread directly in a member function. The key to do this is utilizing adapter objects, that translate the C-stylish callback into a call to a member function. This is explained in detail in the article Use member functions for C-style callbacks and threads - a general solution. Using the techiques described there, creating threads becomes real fun:

                #include "stdafx.h"
                #include "win_adapter.h" // This header file contains the "magic" stuff

                class Test
                {
                public:

                // Thread should be started in this function. 
                // Note that we can use \*any\* type for the single thread parameter
                virtual DWORD ThreadStart( LPCTSTR pszName )
                {
                    printf( "  Hello, I'm a Thread and my name is: %s\\n", pszName );
                    return 0;
                }
                

                };

                void main()
                {
                Test test;

                // Creating a thread that starts execution in a member function
                LPCTSTR pszThreadName = "Joe, the funny thread";
                HANDLE hThread = win::beginthreadex( &test, &Test::ThreadStart, pszThreadName );
                
                // Waiting for thread termination
                WaitForSingleObject( hThread, INFINITE );
                CloseHandle( hThread );
                

                }

                Of course this makes live and code a lot nicer, because you don't have to write all those static wrappers including ugly casts and so on. And the best thing is, that all you need to use it is to include one single header file! No CPP file to add to your project, no libs, no interface or class to derive from, no structural dependencies at all. :-D (Ehm, yes... I am a bit proud about this piece of code :-O ) -- Daniel Lohmann http://www.losoft.de (Hey, this page is worth looking! You can find some free and handy NT tools there :-D )

                T Offline
                T Offline
                Tomasz Sowinski
                wrote on last edited by
                #7

                Daniel Lohmann wrote: no interface or class to derive from, no structural dependencies at all. So why Test::ThreadStart is virtual? Please note that I haven't read your article yet. Can you explain in 25 words or less? :) Tomasz Sowinski -- http://www.shooltz.com

                What is "scratch" and why can everything be made from it?

                D 1 Reply Last reply
                0
                • D Daniel Lohmann

                  Even while thread functions follow the calling conventions of a standard C function and therfore have to be static functions, it is not impossible to create a thread directly in a member function. The key to do this is utilizing adapter objects, that translate the C-stylish callback into a call to a member function. This is explained in detail in the article Use member functions for C-style callbacks and threads - a general solution. Using the techiques described there, creating threads becomes real fun:

                  #include "stdafx.h"
                  #include "win_adapter.h" // This header file contains the "magic" stuff

                  class Test
                  {
                  public:

                  // Thread should be started in this function. 
                  // Note that we can use \*any\* type for the single thread parameter
                  virtual DWORD ThreadStart( LPCTSTR pszName )
                  {
                      printf( "  Hello, I'm a Thread and my name is: %s\\n", pszName );
                      return 0;
                  }
                  

                  };

                  void main()
                  {
                  Test test;

                  // Creating a thread that starts execution in a member function
                  LPCTSTR pszThreadName = "Joe, the funny thread";
                  HANDLE hThread = win::beginthreadex( &test, &Test::ThreadStart, pszThreadName );
                  
                  // Waiting for thread termination
                  WaitForSingleObject( hThread, INFINITE );
                  CloseHandle( hThread );
                  

                  }

                  Of course this makes live and code a lot nicer, because you don't have to write all those static wrappers including ugly casts and so on. And the best thing is, that all you need to use it is to include one single header file! No CPP file to add to your project, no libs, no interface or class to derive from, no structural dependencies at all. :-D (Ehm, yes... I am a bit proud about this piece of code :-O ) -- Daniel Lohmann http://www.losoft.de (Hey, this page is worth looking! You can find some free and handy NT tools there :-D )

                  C Offline
                  C Offline
                  CoY0te
                  wrote on last edited by
                  #8

                  Thanks - looks really nice indeed.:-D Anyway, I don't need any serious thread managment at this time, and I don't store the thread handle at all. I just have to run it and wait till it finishes the job, but I don't have to wait till process it really quits. All I care is when the data will be ready. ;) [ CoY0te ] Railgun is like a Gilette Mach 3 - it does the job with one, easy stroke.

                  D 1 Reply Last reply
                  0
                  • T Tomasz Sowinski

                    Daniel Lohmann wrote: no interface or class to derive from, no structural dependencies at all. So why Test::ThreadStart is virtual? Please note that I haven't read your article yet. Can you explain in 25 words or less? :) Tomasz Sowinski -- http://www.shooltz.com

                    What is "scratch" and why can everything be made from it?

                    D Offline
                    D Offline
                    Daniel Lohmann
                    wrote on last edited by
                    #9

                    Tomasz Sowinski wrote: So why Test::ThreadStart is virtual? Please note that I haven't read your article yet. Can you explain in 25 words or less? Ehm, just to show that it is possible to use even virtual functions as thread starters. However, it does not have to be virtual. It just a member function. (Oh, sorry, that's about 33 words ;-) ) -- Daniel Lohmann http://www.losoft.de (Hey, this page is worth looking! You can find some free and handy NT tools there :-D )

                    1 Reply Last reply
                    0
                    • C CoY0te

                      Thanks - looks really nice indeed.:-D Anyway, I don't need any serious thread managment at this time, and I don't store the thread handle at all. I just have to run it and wait till it finishes the job, but I don't have to wait till process it really quits. All I care is when the data will be ready. ;) [ CoY0te ] Railgun is like a Gilette Mach 3 - it does the job with one, easy stroke.

                      D Offline
                      D Offline
                      Daniel Lohmann
                      wrote on last edited by
                      #10

                      Okay, if your stuff works right now you have no reason to change it :) However, please note that the described technique has nothing to do with "serious thread management". It just shows how to use member functions where C-style callbacks are expected. This is exactly what you asked in your original post: How to do the conversion from a pointer to a member function to THREAD_START_ROUTINE :-D -- Daniel Lohmann http://www.losoft.de (Hey, this page is worth looking! You can find some free and handy NT tools there :-D )

                      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