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. C++ Multiple inheritance

C++ Multiple inheritance

Scheduled Pinned Locked Moved C / C++ / MFC
helpc++hardwareoopquestion
22 Posts 6 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.
  • S ScotDolan

    I currently get a C++ compiler error 32385: Ambiguous access of CreateNewThread in 'mainloop' Now, The cause of this is because the mainloop class inherits, ClxThread object, and Poll_LenzeInvertors object. The Poll_LenzesInvertors objects also inherits ClxThread object. The ClxThread object has a function called CreateNewThread() that spinns a thread of virtual function called ThreadFunc(). I used the ClxThread to create OO way to create threads. Howver, this seems to be the problem with multiple inheritenace. I would like to find a solution to this problem and still be capable of using my ClxThread Object. Any advise would be helpful. Is there a way to distrigish which base class you are trying to call? Should i just rewrite ClxThread so, it does not have to be inherited to work... Scott

    Scott Dolan Jernie Corporation Engineering & Manufacturing Software, Hardware, & Enclosures

    J Offline
    J Offline
    jhwurmbach
    wrote on last edited by
    #4

    Try overloading CreateNewThread() in your derived class. There you can now call ClxThread::CreateNewThread() or Poll_LenzesInvertors::CreateNewThread() - whatever your logic requires.


    Failure is not an option - it's built right in.

    1 Reply Last reply
    0
    • S ScotDolan

      I currently get a C++ compiler error 32385: Ambiguous access of CreateNewThread in 'mainloop' Now, The cause of this is because the mainloop class inherits, ClxThread object, and Poll_LenzeInvertors object. The Poll_LenzesInvertors objects also inherits ClxThread object. The ClxThread object has a function called CreateNewThread() that spinns a thread of virtual function called ThreadFunc(). I used the ClxThread to create OO way to create threads. Howver, this seems to be the problem with multiple inheritenace. I would like to find a solution to this problem and still be capable of using my ClxThread Object. Any advise would be helpful. Is there a way to distrigish which base class you are trying to call? Should i just rewrite ClxThread so, it does not have to be inherited to work... Scott

      Scott Dolan Jernie Corporation Engineering & Manufacturing Software, Hardware, & Enclosures

      C Offline
      C Offline
      Cedric Moonen
      wrote on last edited by
      #5

      I'm not sure to have fully understood your description (a small drawing or scheme would be usefull here). Is the case described here[^] the problem ? Try to make the inheritance virtual: class MyClass : public virtual CMyBase But in general, this kind of situation should be avoided if possible.


      Cédric Moonen Software developer
      Charting control [v1.2]

      S 2 Replies Last reply
      0
      • S ScotDolan

        Cedria, The dread problem is exactly what i am seeing and the solution you provide works. That web site was helpful also. Scott

        Scott Dolan Jernie Corporation Engineering & Manufacturing Software, Hardware, & Enclosures

        S Offline
        S Offline
        ScotDolan
        wrote on last edited by
        #6

        thank you.

        Scott Dolan Jernie Corporation Engineering & Manufacturing Software, Hardware, & Enclosures

        1 Reply Last reply
        0
        • C Cedric Moonen

          I'm not sure to have fully understood your description (a small drawing or scheme would be usefull here). Is the case described here[^] the problem ? Try to make the inheritance virtual: class MyClass : public virtual CMyBase But in general, this kind of situation should be avoided if possible.


          Cédric Moonen Software developer
          Charting control [v1.2]

          S Offline
          S Offline
          ScotDolan
          wrote on last edited by
          #7

          Cedria, The dread problem is exactly what i am seeing and the solution you provide works. That web site was helpful also. Scott

          Scott Dolan Jernie Corporation Engineering & Manufacturing Software, Hardware, & Enclosures

          S 1 Reply Last reply
          0
          • C Cedric Moonen

            I'm not sure to have fully understood your description (a small drawing or scheme would be usefull here). Is the case described here[^] the problem ? Try to make the inheritance virtual: class MyClass : public virtual CMyBase But in general, this kind of situation should be avoided if possible.


            Cédric Moonen Software developer
            Charting control [v1.2]

            S Offline
            S Offline
            ScotDolan
            wrote on last edited by
            #8

            Cédric, I miss spoken, the virtual keyword did make the code compile but it still did not function as as expected. I want to achieve the following functionality of having two ClxThread base objects using inheritence. I basiclly develop a ClxThread class object that provides all the functionaliy to create, kill, suspend, and start a Thread function. I now realize my design decision of making clxthread as base class was probably not the best idea. However, it does make it easy to turn any class into a little worker class/app. Is thare any way i can achieve my desire results. Desire Results Actual Results

            ClxThread ClxThread
            \ / \
            \ / \
            \ / \
            Poll ClxThread Poll |
            \ / \ /
            \ / \ /
            \ / \ /
            mainloop mailoop

            Here is the header for the clx thread class class ClxThread { public: ClxThread(); virtual ~ClxThread(); typedef unsigned (__stdcall *PTHREADFUNC)(void *); //Thread Management bool CreateNewThread(void); bool CreateNewThread(PTHREADFUNC pThreadFunc); bool Wait(); //Wait for thread to end bool Suspend(); //Suspend the thread bool Resume(); //Resume a suspended thread bool Kill(); //Terminate a thread bool IsActive(); //Check for activity //override these functions in the derived class virtual void ThreadEntry(){ } virtual void ThreadExit(){ } virtual void ThreadRun(){ } //a friend //friend DWORD WINAPI _ThreadFunc(LPVOID pvThread); static UINT WINAPI _ThreadFunc(LPVOID pParam); public: HANDLE m_hThread; // Thread handle UINT uiThreadId; // bool m_bActive; //activity indicator DWORD m_lpId; //Thread ID };

            Scott Dolan Jernie Corporation Engineering & Manufacturing Software, Hardware, & Enclosures

            C M 2 Replies Last reply
            0
            • S ScotDolan

              Cédric, I miss spoken, the virtual keyword did make the code compile but it still did not function as as expected. I want to achieve the following functionality of having two ClxThread base objects using inheritence. I basiclly develop a ClxThread class object that provides all the functionaliy to create, kill, suspend, and start a Thread function. I now realize my design decision of making clxthread as base class was probably not the best idea. However, it does make it easy to turn any class into a little worker class/app. Is thare any way i can achieve my desire results. Desire Results Actual Results

              ClxThread ClxThread
              \ / \
              \ / \
              \ / \
              Poll ClxThread Poll |
              \ / \ /
              \ / \ /
              \ / \ /
              mainloop mailoop

              Here is the header for the clx thread class class ClxThread { public: ClxThread(); virtual ~ClxThread(); typedef unsigned (__stdcall *PTHREADFUNC)(void *); //Thread Management bool CreateNewThread(void); bool CreateNewThread(PTHREADFUNC pThreadFunc); bool Wait(); //Wait for thread to end bool Suspend(); //Suspend the thread bool Resume(); //Resume a suspended thread bool Kill(); //Terminate a thread bool IsActive(); //Check for activity //override these functions in the derived class virtual void ThreadEntry(){ } virtual void ThreadExit(){ } virtual void ThreadRun(){ } //a friend //friend DWORD WINAPI _ThreadFunc(LPVOID pvThread); static UINT WINAPI _ThreadFunc(LPVOID pParam); public: HANDLE m_hThread; // Thread handle UINT uiThreadId; // bool m_bActive; //activity indicator DWORD m_lpId; //Thread ID };

              Scott Dolan Jernie Corporation Engineering & Manufacturing Software, Hardware, & Enclosures

              C Offline
              C Offline
              Cedric Moonen
              wrote on last edited by
              #9

              :confused: Why do you want to do such a thing ? I really don't understand why you want to inherit from ClxThread once again. You know that the functionalities of your class will be inherited even if there is a class (Poll) in between ?


              Cédric Moonen Software developer
              Charting control [v1.2]

              S 1 Reply Last reply
              0
              • S ScotDolan

                I currently get a C++ compiler error 32385: Ambiguous access of CreateNewThread in 'mainloop' Now, The cause of this is because the mainloop class inherits, ClxThread object, and Poll_LenzeInvertors object. The Poll_LenzesInvertors objects also inherits ClxThread object. The ClxThread object has a function called CreateNewThread() that spinns a thread of virtual function called ThreadFunc(). I used the ClxThread to create OO way to create threads. Howver, this seems to be the problem with multiple inheritenace. I would like to find a solution to this problem and still be capable of using my ClxThread Object. Any advise would be helpful. Is there a way to distrigish which base class you are trying to call? Should i just rewrite ClxThread so, it does not have to be inherited to work... Scott

                Scott Dolan Jernie Corporation Engineering & Manufacturing Software, Hardware, & Enclosures

                L Offline
                L Offline
                led mike
                wrote on last edited by
                #10

                ScotDolan wrote:

                the mainloop class inherits, ClxThread object, and Poll_LenzeInvertors object. The Poll_LenzesInvertors objects also inherits ClxThread object.

                Not a good idea. This is known as the diamond multiple inheritance[^] problem and is usually indicative of a design problem.

                led mike

                1 Reply Last reply
                0
                • S ScotDolan

                  Cédric, I miss spoken, the virtual keyword did make the code compile but it still did not function as as expected. I want to achieve the following functionality of having two ClxThread base objects using inheritence. I basiclly develop a ClxThread class object that provides all the functionaliy to create, kill, suspend, and start a Thread function. I now realize my design decision of making clxthread as base class was probably not the best idea. However, it does make it easy to turn any class into a little worker class/app. Is thare any way i can achieve my desire results. Desire Results Actual Results

                  ClxThread ClxThread
                  \ / \
                  \ / \
                  \ / \
                  Poll ClxThread Poll |
                  \ / \ /
                  \ / \ /
                  \ / \ /
                  mainloop mailoop

                  Here is the header for the clx thread class class ClxThread { public: ClxThread(); virtual ~ClxThread(); typedef unsigned (__stdcall *PTHREADFUNC)(void *); //Thread Management bool CreateNewThread(void); bool CreateNewThread(PTHREADFUNC pThreadFunc); bool Wait(); //Wait for thread to end bool Suspend(); //Suspend the thread bool Resume(); //Resume a suspended thread bool Kill(); //Terminate a thread bool IsActive(); //Check for activity //override these functions in the derived class virtual void ThreadEntry(){ } virtual void ThreadExit(){ } virtual void ThreadRun(){ } //a friend //friend DWORD WINAPI _ThreadFunc(LPVOID pvThread); static UINT WINAPI _ThreadFunc(LPVOID pParam); public: HANDLE m_hThread; // Thread handle UINT uiThreadId; // bool m_bActive; //activity indicator DWORD m_lpId; //Thread ID };

                  Scott Dolan Jernie Corporation Engineering & Manufacturing Software, Hardware, & Enclosures

                  M Offline
                  M Offline
                  Mark Salsbery
                  wrote on last edited by
                  #11

                  My 2 cents... From the sound of the class names involved - If you think in terms of "is a..." and "has a..." where "is a..." means you derive from and "has a..." means you have a member object, it sounds like Poll_LenzeInvertors doesn't need to BE a thread object but needs to HAVE a thread object. The same with mainloop - is mainloop a poll object, or does it need to have a poll object. Maybe something to think about in the design. If not, simply ignore :) Mark

                  "Posting a VB.NET question in the C++ forum will end in tears." Chris Maunder

                  S 1 Reply Last reply
                  0
                  • C Cedric Moonen

                    :confused: Why do you want to do such a thing ? I really don't understand why you want to inherit from ClxThread once again. You know that the functionalities of your class will be inherited even if there is a class (Poll) in between ?


                    Cédric Moonen Software developer
                    Charting control [v1.2]

                    S Offline
                    S Offline
                    ScotDolan
                    wrote on last edited by
                    #12

                    I want to inherit ClxThread twice because, i need to create two ClxThreads which are just worker threads. One in the Mainloop and one in Poll. It is looking like I should change ClxThread to have the capablities to be object within Mainloop and Poll instead of a inherited object. class ClxThread { public: ClxThread(); virtual ~ClxThread(); typedef unsigned (__stdcall *PTHREADFUNC)(void *); //Thread Management bool CreateNewThread(void); bool CreateNewThread(PTHREADFUNC pThreadFunc); bool Wait(); //Wait for thread to end bool Suspend(); //Suspend the thread bool Resume(); //Resume a suspended thread bool Kill(); //Terminate a thread bool IsActive(); //Check for activity //override these functions in the derived class virtual void ThreadEntry(){ } virtual void ThreadExit(){ } virtual void ThreadRun(){ } //a friend //friend DWORD WINAPI _ThreadFunc(LPVOID pvThread); static UINT WINAPI _ThreadFunc(LPVOID pParam); public: HANDLE m_hThread; // Thread handle UINT uiThreadId; // bool m_bActive; //activity indicator DWORD m_lpId; //Thread ID }; The main loop classes header. class mainloop : public LENZE_8200_MOTION, private ClxThread { public: mainloop(); ~mainloop(); void Start(void){ CreateNewThread( ); };// Start Clx thread objecty protected: // The Setup Function the MC362X void init_mc362X(void); bool read_mc362x(void); bool read_lenze_cfg_sheet(void); bool read_independencer( void ); private: // This is function that becomes the worker thread. void ThreadRun(void); MC362X_MOTION isacard; //Defines Motion object ClxUdp cmd_socket; // ClxUdp data_socket; // bool isRaising; void Raise(void); bool Balance_A( double position ); void Balance_B(void); void init_lift(void); void lift(void); private: bool m_bBalanced; char m_cStateCurrent; char m_cStateLast; bool m_bDown; bool m_bEStop; bool m_bPortUp; bool m_bStarboard; bool m_bCanopyOpen; bool m_bUp; char m_cCommand; }; The Poll classer headers class LENZE_8200_MOTION : public ClxThread, protected CLX_LENZE_8200 { public: LENZE_8200_MOTION(void); ~LENZE_8200_MOTION(void); public: bool init_lenze8200( int comm_port, int baud_rate, long timeout_ms, int maxtxfailures ); bool start_lenze8200(void){ return CreateNewThread(); } //These public member functions are to set, get and control Lift axis lenze 8200

                    1 Reply Last reply
                    0
                    • M Mark Salsbery

                      My 2 cents... From the sound of the class names involved - If you think in terms of "is a..." and "has a..." where "is a..." means you derive from and "has a..." means you have a member object, it sounds like Poll_LenzeInvertors doesn't need to BE a thread object but needs to HAVE a thread object. The same with mainloop - is mainloop a poll object, or does it need to have a poll object. Maybe something to think about in the design. If not, simply ignore :) Mark

                      "Posting a VB.NET question in the C++ forum will end in tears." Chris Maunder

                      S Offline
                      S Offline
                      ScotDolan
                      wrote on last edited by
                      #13

                      Mark, I think you are right, I am thinking I need stop inheriting a ClxThread and declare a clxthread object within the mainloop and poll_lenze class. However, I have been struggling to pass a void ThreadFunc(void) into CreateNewThread(PTHREADFUNC pThreadFunc); which turns the function ThreadFunc into working thread/function. However, if i create a function in mainloop like this static UINT WINAPI MaintainingThreadProc(LPVOID pParam); and pass it into CreateNewThread(PTHREADFUNC pThreadFunc) Than, MaintainingThreadProc() function becomes a worker thread. I really would like to just pass the stardard void ThreadFunc(void) function prototype if possible. class ClxThread { public: ClxThread(); virtual ~ClxThread(); typedef unsigned (__stdcall *PTHREADFUNC)(void *); //Thread Management bool CreateNewThread(void); bool CreateNewThread(PTHREADFUNC pThreadFunc); bool Wait(); //Wait for thread to end bool Suspend(); //Suspend the thread bool Resume(); //Resume a suspended thread bool Kill(); //Terminate a thread bool IsActive(); //Check for activity //override these functions in the derived class virtual void ThreadEntry(){ } virtual void ThreadExit(){ } virtual void ThreadRun(){ } //a friend //friend DWORD WINAPI _ThreadFunc(LPVOID pvThread); static UINT WINAPI _ThreadFunc(LPVOID pParam); public: HANDLE m_hThread; // Thread handle UINT uiThreadId; // bool m_bActive; //activity indicator DWORD m_lpId; //Thread ID };

                      Scott Dolan Jernie Corporation Engineering & Manufacturing Software, Hardware, & Enclosures

                      M L 2 Replies Last reply
                      0
                      • S ScotDolan

                        Mark, I think you are right, I am thinking I need stop inheriting a ClxThread and declare a clxthread object within the mainloop and poll_lenze class. However, I have been struggling to pass a void ThreadFunc(void) into CreateNewThread(PTHREADFUNC pThreadFunc); which turns the function ThreadFunc into working thread/function. However, if i create a function in mainloop like this static UINT WINAPI MaintainingThreadProc(LPVOID pParam); and pass it into CreateNewThread(PTHREADFUNC pThreadFunc) Than, MaintainingThreadProc() function becomes a worker thread. I really would like to just pass the stardard void ThreadFunc(void) function prototype if possible. class ClxThread { public: ClxThread(); virtual ~ClxThread(); typedef unsigned (__stdcall *PTHREADFUNC)(void *); //Thread Management bool CreateNewThread(void); bool CreateNewThread(PTHREADFUNC pThreadFunc); bool Wait(); //Wait for thread to end bool Suspend(); //Suspend the thread bool Resume(); //Resume a suspended thread bool Kill(); //Terminate a thread bool IsActive(); //Check for activity //override these functions in the derived class virtual void ThreadEntry(){ } virtual void ThreadExit(){ } virtual void ThreadRun(){ } //a friend //friend DWORD WINAPI _ThreadFunc(LPVOID pvThread); static UINT WINAPI _ThreadFunc(LPVOID pParam); public: HANDLE m_hThread; // Thread handle UINT uiThreadId; // bool m_bActive; //activity indicator DWORD m_lpId; //Thread ID };

                        Scott Dolan Jernie Corporation Engineering & Manufacturing Software, Hardware, & Enclosures

                        M Offline
                        M Offline
                        Mark Salsbery
                        wrote on last edited by
                        #14

                        ScotDolan wrote:

                        I am thinking I need stop inheriting a ClxThread and declare a clxthread object within the mainloop and poll_lenze class.

                        Maybe :) Whatever is best for your design. I suppose since mainloop and poll_lenze both have associated threads, they could each derive from ClxThread, but mainloop, then, shouldn't be derived from poll_lenze since mainloop is not a poll_lenze.

                        ScotDolan wrote:

                        if i create a function in mainloop like this static UINT WINAPI MaintainingThreadProc(LPVOID pParam); and pass it into CreateNewThread(PTHREADFUNC pThreadFunc)

                        I'm not sure how you've implemented your ClxThread class, but from the header info, CreateNewThread(PTHREADFUNC pThreadFunc) needs as a parameter a pointer to a function declared as unsigned __stdcall func(void *). You shouldn't be able to pass a pointer to a function declared as UINT WINAPI MaintainingThreadProc(LPVOID pParam). Since you've put a nice little wrapper around a thread, I'm not sure why you need to pass a thread proc in... Mark

                        "Posting a VB.NET question in the C++ forum will end in tears." Chris Maunder

                        1 Reply Last reply
                        0
                        • S ScotDolan

                          Mark, I think you are right, I am thinking I need stop inheriting a ClxThread and declare a clxthread object within the mainloop and poll_lenze class. However, I have been struggling to pass a void ThreadFunc(void) into CreateNewThread(PTHREADFUNC pThreadFunc); which turns the function ThreadFunc into working thread/function. However, if i create a function in mainloop like this static UINT WINAPI MaintainingThreadProc(LPVOID pParam); and pass it into CreateNewThread(PTHREADFUNC pThreadFunc) Than, MaintainingThreadProc() function becomes a worker thread. I really would like to just pass the stardard void ThreadFunc(void) function prototype if possible. class ClxThread { public: ClxThread(); virtual ~ClxThread(); typedef unsigned (__stdcall *PTHREADFUNC)(void *); //Thread Management bool CreateNewThread(void); bool CreateNewThread(PTHREADFUNC pThreadFunc); bool Wait(); //Wait for thread to end bool Suspend(); //Suspend the thread bool Resume(); //Resume a suspended thread bool Kill(); //Terminate a thread bool IsActive(); //Check for activity //override these functions in the derived class virtual void ThreadEntry(){ } virtual void ThreadExit(){ } virtual void ThreadRun(){ } //a friend //friend DWORD WINAPI _ThreadFunc(LPVOID pvThread); static UINT WINAPI _ThreadFunc(LPVOID pParam); public: HANDLE m_hThread; // Thread handle UINT uiThreadId; // bool m_bActive; //activity indicator DWORD m_lpId; //Thread ID };

                          Scott Dolan Jernie Corporation Engineering & Manufacturing Software, Hardware, & Enclosures

                          L Offline
                          L Offline
                          led mike
                          wrote on last edited by
                          #15

                          ScotDolan wrote:

                          However, I have been struggling to pass a void ThreadFunc(void) into CreateNewThread(PTHREADFUNC pThreadFunc); which turns the function ThreadFunc into working thread/function.

                          Why would you do that. Wouldn't a thread class encapsulate the HANDLE and the Thread function?

                          led mike

                          S 1 Reply Last reply
                          0
                          • L led mike

                            ScotDolan wrote:

                            However, I have been struggling to pass a void ThreadFunc(void) into CreateNewThread(PTHREADFUNC pThreadFunc); which turns the function ThreadFunc into working thread/function.

                            Why would you do that. Wouldn't a thread class encapsulate the HANDLE and the Thread function?

                            led mike

                            S Offline
                            S Offline
                            ScotDolan
                            wrote on last edited by
                            #16

                            The purpose of the thread class is to make simple functions that consolidate, hide all the mondain task that need to be performed to start, kill, suspend, resume, a thread. The object is to try to prevent any Operating System specific code from getting into the my mainloop and poll-lenze code. This will make it easier for me to port the code over to Linux, Unix or any other os that supports C++. This is why the i use ThreadEnter(),ThreadRun(), and ThreadExit() can all be override. Because, ThreadEnter(),ThreadRun(), and ThreadExit() get called in the worker thread. other object is to keep the create a spreate function where the thread code goes. The end results is that when it comes time to port the code over to a new Os, i should only have to rewrite ClxThread. #pragma once class ClxThread { public: ClxThread(); virtual ~ClxThread(); typedef unsigned (__stdcall *PTHREADFUNC)(void *); //Thread Management bool CreateNewThread(void); bool CreateNewThread(PTHREADFUNC pThreadFunc); bool Wait(); //Wait for thread to end bool Suspend(); //Suspend the thread bool Resume(); //Resume a suspended thread bool Kill(); //Terminate a thread bool IsActive(); //Check for activity //override these functions in the derived class virtual void ThreadEntry(){ } virtual void ThreadExit(){ } virtual void ThreadRun(){ } //a friend //friend DWORD WINAPI _ThreadFunc(LPVOID pvThread); static UINT WINAPI _ThreadFunc(LPVOID pParam); public: HANDLE m_hThread; // Thread handle UINT uiThreadId; // bool m_bActive; //activity indicator DWORD m_lpId; //Thread ID }; #include "stdafx.h" #include ".\ClxThread.h" #include /********************************************************************************************* Purpose: Constructor **********************************************************************************************/ ClxThread::ClxThread() { m_hThread = NULL; m_bActive = false; uiThreadId = NULL; } /********************************************************************************************* Purpose: Destructor **********************************************************************************************/ ClxThread::~ClxThread() { Kill(); } bool ClxThread::CreateNewThread(PTHREADFUNC pThreadFunc) { if( m_hThread == NULL ) { // _beginthreadex(Security attributes, stack, Thread proc, Thread param, creation mode, Thread ID) m_hThread = (HANDLE)_beginthreadex(NULL, 0

                            M L 2 Replies Last reply
                            0
                            • S ScotDolan

                              The purpose of the thread class is to make simple functions that consolidate, hide all the mondain task that need to be performed to start, kill, suspend, resume, a thread. The object is to try to prevent any Operating System specific code from getting into the my mainloop and poll-lenze code. This will make it easier for me to port the code over to Linux, Unix or any other os that supports C++. This is why the i use ThreadEnter(),ThreadRun(), and ThreadExit() can all be override. Because, ThreadEnter(),ThreadRun(), and ThreadExit() get called in the worker thread. other object is to keep the create a spreate function where the thread code goes. The end results is that when it comes time to port the code over to a new Os, i should only have to rewrite ClxThread. #pragma once class ClxThread { public: ClxThread(); virtual ~ClxThread(); typedef unsigned (__stdcall *PTHREADFUNC)(void *); //Thread Management bool CreateNewThread(void); bool CreateNewThread(PTHREADFUNC pThreadFunc); bool Wait(); //Wait for thread to end bool Suspend(); //Suspend the thread bool Resume(); //Resume a suspended thread bool Kill(); //Terminate a thread bool IsActive(); //Check for activity //override these functions in the derived class virtual void ThreadEntry(){ } virtual void ThreadExit(){ } virtual void ThreadRun(){ } //a friend //friend DWORD WINAPI _ThreadFunc(LPVOID pvThread); static UINT WINAPI _ThreadFunc(LPVOID pParam); public: HANDLE m_hThread; // Thread handle UINT uiThreadId; // bool m_bActive; //activity indicator DWORD m_lpId; //Thread ID }; #include "stdafx.h" #include ".\ClxThread.h" #include /********************************************************************************************* Purpose: Constructor **********************************************************************************************/ ClxThread::ClxThread() { m_hThread = NULL; m_bActive = false; uiThreadId = NULL; } /********************************************************************************************* Purpose: Destructor **********************************************************************************************/ ClxThread::~ClxThread() { Kill(); } bool ClxThread::CreateNewThread(PTHREADFUNC pThreadFunc) { if( m_hThread == NULL ) { // _beginthreadex(Security attributes, stack, Thread proc, Thread param, creation mode, Thread ID) m_hThread = (HANDLE)_beginthreadex(NULL, 0

                              M Offline
                              M Offline
                              Mark Salsbery
                              wrote on last edited by
                              #17

                              But again, why do you need a member function that takes a function pointer as an argument if you've encapsulated the threadproc so nicely? Your virtual functions expose derived classes to the threadproc generically. Mark

                              "Posting a VB.NET question in the C++ forum will end in tears." Chris Maunder

                              1 Reply Last reply
                              0
                              • S ScotDolan

                                The purpose of the thread class is to make simple functions that consolidate, hide all the mondain task that need to be performed to start, kill, suspend, resume, a thread. The object is to try to prevent any Operating System specific code from getting into the my mainloop and poll-lenze code. This will make it easier for me to port the code over to Linux, Unix or any other os that supports C++. This is why the i use ThreadEnter(),ThreadRun(), and ThreadExit() can all be override. Because, ThreadEnter(),ThreadRun(), and ThreadExit() get called in the worker thread. other object is to keep the create a spreate function where the thread code goes. The end results is that when it comes time to port the code over to a new Os, i should only have to rewrite ClxThread. #pragma once class ClxThread { public: ClxThread(); virtual ~ClxThread(); typedef unsigned (__stdcall *PTHREADFUNC)(void *); //Thread Management bool CreateNewThread(void); bool CreateNewThread(PTHREADFUNC pThreadFunc); bool Wait(); //Wait for thread to end bool Suspend(); //Suspend the thread bool Resume(); //Resume a suspended thread bool Kill(); //Terminate a thread bool IsActive(); //Check for activity //override these functions in the derived class virtual void ThreadEntry(){ } virtual void ThreadExit(){ } virtual void ThreadRun(){ } //a friend //friend DWORD WINAPI _ThreadFunc(LPVOID pvThread); static UINT WINAPI _ThreadFunc(LPVOID pParam); public: HANDLE m_hThread; // Thread handle UINT uiThreadId; // bool m_bActive; //activity indicator DWORD m_lpId; //Thread ID }; #include "stdafx.h" #include ".\ClxThread.h" #include /********************************************************************************************* Purpose: Constructor **********************************************************************************************/ ClxThread::ClxThread() { m_hThread = NULL; m_bActive = false; uiThreadId = NULL; } /********************************************************************************************* Purpose: Destructor **********************************************************************************************/ ClxThread::~ClxThread() { Kill(); } bool ClxThread::CreateNewThread(PTHREADFUNC pThreadFunc) { if( m_hThread == NULL ) { // _beginthreadex(Security attributes, stack, Thread proc, Thread param, creation mode, Thread ID) m_hThread = (HANDLE)_beginthreadex(NULL, 0

                                L Offline
                                L Offline
                                led mike
                                wrote on last edited by
                                #18

                                I don't know why you have: bool CreateNewThread(PTHREADFUNC pThreadFunc); virtual void ThreadEntry(){ } virtual void ThreadExit(){ } It would seem the virtual ThreadRun() would be a complete implementation alone.

                                led mike

                                S 1 Reply Last reply
                                0
                                • L led mike

                                  I don't know why you have: bool CreateNewThread(PTHREADFUNC pThreadFunc); virtual void ThreadEntry(){ } virtual void ThreadExit(){ } It would seem the virtual ThreadRun() would be a complete implementation alone.

                                  led mike

                                  S Offline
                                  S Offline
                                  ScotDolan
                                  wrote on last edited by
                                  #19

                                  The purpose of bool CreateNewThread(PTHREADFUNC pThreadFunc); is so ClxThread can be used without having to be inherited. So, i can declare a ClxThread object inside of mainloop instead of inheriting clxthread. Then, i pass in the member function of mainloop into ClxThread define object and it will run in a different thread. This way, i can uses ClxThread as a inherited object or static object. This would prevent the dreaded diamond effect.

                                  Scott Dolan Jernie Corporation Engineering & Manufacturing Software, Hardware, & Enclosures

                                  L 1 Reply Last reply
                                  0
                                  • S ScotDolan

                                    The purpose of bool CreateNewThread(PTHREADFUNC pThreadFunc); is so ClxThread can be used without having to be inherited. So, i can declare a ClxThread object inside of mainloop instead of inheriting clxthread. Then, i pass in the member function of mainloop into ClxThread define object and it will run in a different thread. This way, i can uses ClxThread as a inherited object or static object. This would prevent the dreaded diamond effect.

                                    Scott Dolan Jernie Corporation Engineering & Manufacturing Software, Hardware, & Enclosures

                                    L Offline
                                    L Offline
                                    led mike
                                    wrote on last edited by
                                    #20

                                    That makes no sense at all. In that scenario the class has no control over the thread function and therefore the concept of encapsulation does not exist.

                                    ScotDolan wrote:

                                    The purpose of bool CreateNewThread(PTHREADFUNC pThreadFunc); is so ClxThread can be used without having to be inherited. So, i can declare a ClxThread object inside of mainloop instead of inheriting clxthread.

                                    For that scenario why wouldn't you declare an inherited class "inside of mainloop"? :confused:

                                    led mike

                                    S 1 Reply Last reply
                                    0
                                    • L led mike

                                      That makes no sense at all. In that scenario the class has no control over the thread function and therefore the concept of encapsulation does not exist.

                                      ScotDolan wrote:

                                      The purpose of bool CreateNewThread(PTHREADFUNC pThreadFunc); is so ClxThread can be used without having to be inherited. So, i can declare a ClxThread object inside of mainloop instead of inheriting clxthread.

                                      For that scenario why wouldn't you declare an inherited class "inside of mainloop"? :confused:

                                      led mike

                                      S Offline
                                      S Offline
                                      ScotDolan
                                      wrote on last edited by
                                      #21

                                      For that scenario why wouldn't you declare an inherited class "inside of mainloop"? Mike, That is exactly what I am trying to do. However, I want mainloop to inherit ClxThread. but i also need it to inherit a Poll_Invertors. The problem is Poll_Invertors also inherits a ClxThread to create its own thread. The results is i end up with only one thread even being started ie basicly dreaded diamond.

                                         mainloop                           
                                           /  \\
                                          /    \\
                                         /      \\
                                        /        \\
                                      

                                      ClxThread Poll_Invertors
                                      \
                                      \
                                      \
                                      ClxThread

                                      The mainloop code class mainloop : public Poll_Invertors, public ClxThread { public: mainloop(); ~mainloop(); void Start(void){ CreateNewThread( ); };// Start Clx thread objecty protected: // The Setup Function the MC362X void init_mc362X(void); bool read_mc362x(void); bool read_lenze_cfg_sheet(void); bool read_independencer( void ); private: void ThreadRun( void ); // This is function that becomes the worker thread. MC362X_MOTION isacard; //Defines Motion object ClxUdp cmd_socket; // ClxUdp data_socket; // } The Poll_Invertors Header lass LENZE_8200_MOTION : public ClxThread, protected CLX_LENZE_8200 { public: LENZE_8200_MOTION(void); ~LENZE_8200_MOTION(void); public: bool init_lenze8200( int comm_port, int baud_rate, long timeout_ms, int maxtxfailures ); bool start_lenze8200(void){ return CreateNewThread(); } //These public member functions are to set, get and control Lift axis lenze 8200 inverter // These function provide a thread safe way to access data member variables that contain // lift axis status information and perform commands. void pitch_set_address( char address ){ return SetAddress( &pitch_axis_data, address ); }; ... char pitch_get_address( void ){ return GetAddress( &pitch_axis_data ); }; private: void ThreadRun(void); // This is the thread function that polls the invertors void RunAll( void ); LNZ82_INVRT_DATA pitch_axis_data; LNZ82_INVRT_DATA roll_axis_data; LNZ82_INVRT_DATA lift_axis_data; LNZ82_INVRT_DATA counterweight_axis_data; ClxSafeQue m_sqInvertorsCmdQue; char m_iInvertorsPollState; char pitch_init(LNZ82_INVRT_DATA *axis); char roll_init(LNZ82_INVRT_DATA *axis); char lift_init(LNZ82_INVRT_DATA *axis); char counterweight_init(LNZ82_INVRT_DATA *axis);

                                      L 1 Reply Last reply
                                      0
                                      • S ScotDolan

                                        For that scenario why wouldn't you declare an inherited class "inside of mainloop"? Mike, That is exactly what I am trying to do. However, I want mainloop to inherit ClxThread. but i also need it to inherit a Poll_Invertors. The problem is Poll_Invertors also inherits a ClxThread to create its own thread. The results is i end up with only one thread even being started ie basicly dreaded diamond.

                                           mainloop                           
                                             /  \\
                                            /    \\
                                           /      \\
                                          /        \\
                                        

                                        ClxThread Poll_Invertors
                                        \
                                        \
                                        \
                                        ClxThread

                                        The mainloop code class mainloop : public Poll_Invertors, public ClxThread { public: mainloop(); ~mainloop(); void Start(void){ CreateNewThread( ); };// Start Clx thread objecty protected: // The Setup Function the MC362X void init_mc362X(void); bool read_mc362x(void); bool read_lenze_cfg_sheet(void); bool read_independencer( void ); private: void ThreadRun( void ); // This is function that becomes the worker thread. MC362X_MOTION isacard; //Defines Motion object ClxUdp cmd_socket; // ClxUdp data_socket; // } The Poll_Invertors Header lass LENZE_8200_MOTION : public ClxThread, protected CLX_LENZE_8200 { public: LENZE_8200_MOTION(void); ~LENZE_8200_MOTION(void); public: bool init_lenze8200( int comm_port, int baud_rate, long timeout_ms, int maxtxfailures ); bool start_lenze8200(void){ return CreateNewThread(); } //These public member functions are to set, get and control Lift axis lenze 8200 inverter // These function provide a thread safe way to access data member variables that contain // lift axis status information and perform commands. void pitch_set_address( char address ){ return SetAddress( &pitch_axis_data, address ); }; ... char pitch_get_address( void ){ return GetAddress( &pitch_axis_data ); }; private: void ThreadRun(void); // This is the thread function that polls the invertors void RunAll( void ); LNZ82_INVRT_DATA pitch_axis_data; LNZ82_INVRT_DATA roll_axis_data; LNZ82_INVRT_DATA lift_axis_data; LNZ82_INVRT_DATA counterweight_axis_data; ClxSafeQue m_sqInvertorsCmdQue; char m_iInvertorsPollState; char pitch_init(LNZ82_INVRT_DATA *axis); char roll_init(LNZ82_INVRT_DATA *axis); char lift_init(LNZ82_INVRT_DATA *axis); char counterweight_init(LNZ82_INVRT_DATA *axis);

                                        L Offline
                                        L Offline
                                        led mike
                                        wrote on last edited by
                                        #22

                                        At this point we are having a communication breakdown. I sugggest you take a fresh look at your design. statements like: "I want mainloop to inherit ClxThread. but i also need it to inherit a Poll_Invertors." indicate that you are experiencing myopia. Step away from that thinking completely and try to see a different approach.

                                        led mike

                                        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