Thread: how to pass function pointer as arg in c++

  1. #1
    Registered User
    Join Date
    Mar 2008
    Posts
    58

    how to pass function pointer as arg in c++

    Hello all sorry for the bad english
    how can i pass function pointer as function arg
    let me explain :
    i have Class A inside one of its methods lts call it A::a i start 3 worker threads
    that i initiate in side this class and pass the worker thread to thread pool.
    this worker thread need to invoke Class A method called A::b.
    my question is how can i sent function pointer of A::b to the worker thread
    the worker thread class will get it in the constructor.
    or there is some other way to do it
    i fallow the example from :http://www.parashift.com/c++-faq-lit....html#faq-33.7
    but then i had problem until i try to pass the member argument as another arg.
    here is sample code that dose not work
    Code:
    TestMethod.cpp
    ---------------------------------------
    #include "TestMethod.h"
    #define CALL_MEMBER_FN(object,ptrToMember)  ((object).*(ptrToMember))
    void callit(TestClass& o, FredMemFn p,std::vector<std::string>* vv)
     {
        CALL_MEMBER_FN(o,p)(vv);
     }
    TestMethod::TestMethod()
    {;}
    void TestMethod::Init(TestClass& o, FredMemFn p,std::vector<std::string>* vv1) 
    {
     int h = vv1->size();
     callit(o,p,vv1);
    }
    TestMethod.h
    --------------------------------------
    class TestClass;
    #include <vector>
    typedef  void (TestClass::*FredMemFn)(std::vector<std::string>* vv);  
    class TestMethod 
    {
        public :
            TestMethod();
            void Init(TestClass& o, FredMemFn p,std::vector<std::string>* vv);
        private :
            TestClass* m_TestClass;
    
    };
    
    TestClass.cpp
    ----------------------------------------
    #include "TestClass.h"
    #include "TestMethod.h"
    #include <iostream>
    #include <stdio.h>
    
    using namespace std;
    typedef  void (TestClass::*FredMemFn)(std::vector<std::string>* vv);
    TestClass::TestClass()
    {;}
    TestClass::~TestClass()
    {;}
    void TestClass::SayHelp(std::vector<std::string>* vv){
        cout << "Help" <<endl;
        
    }
    void TestClass::add()
    {
        std::vector<std::string> vv1;
        vv1.push_back("DDDD");
        TestMethod* testMethod = new TestMethod();
        FredMemFn p = &TestClass::SayHelp; 
        testMethod->Init(*this,p,&vv1);  
    }
    
    TestClass.h
    ---------------------------------------- 
    
    #include <vector> 
    class TestClass
    {
        public :
            TestClass();
            ~TestClass();
            void add();
            void SayHelp(std::vector<std::string>* vv1);
          
        private: 
           int m_test;
            
    };
    thank for helping

  2. #2
    The larch
    Join Date
    May 2006
    Posts
    3,573
    If I reorder it to a single file and replace the < and > and provide a main() it works fine for me (prints "Help").

    Code:
    int main()
    {
        TestClass t;
        t.add();
    }
    You may need to be more specific.
    I might be wrong.

    Thank you, anon. You sure know how to recognize different types of trees from quite a long way away.
    Quoted more than 1000 times (I hope).

  3. #3
    Banned master5001's Avatar
    Join Date
    Aug 2001
    Location
    Visalia, CA, USA
    Posts
    3,685
    First of all, the example was explaining how something cannot be done. Just use a static member function.

  4. #4
    Registered User
    Join Date
    Mar 2008
    Posts
    58
    Hello and thanks for the fast reply
    but when i use different class it does not work , i really dont know why .
    Thanks

  5. #5
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    So provide us with a SMALL example of what you are trying to do.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  6. #6
    Banned master5001's Avatar
    Join Date
    Aug 2001
    Location
    Visalia, CA, USA
    Posts
    3,685
    Where is it failing? I don't even see where you are calling code that could even have an issue.

  7. #7
    Registered User
    Join Date
    Mar 2008
    Posts
    58
    ok i did place it with one big main and it does work also .
    maybe the problem is in the includes . im using forward declaration here maybe this is problem also . i don't know
    what im trying to do here i can't give here the real code.
    i just need to make it some how work .
    as i said in my first post in my real app i need to pass to worker thread the ability to use function of the object that started the thread .
    Thanks

  8. #8
    Registered User
    Join Date
    Mar 2008
    Posts
    58
    hu my calling code looks like this :

    Code:
    #include "TestClass.h"
    int  main()
    {   
        TestClass* testClass = new TestClass();
        testClass->add();
    	return 0;
    }
    and it failed on (int h = vv1->size() :

    Code:
    void TestMethod::Init(TestClass& o, FredMemFn p,std::vector<std::string>* vv1) 
    {
     int h = vv1->size();
     
     callit(o,p,vv1);
    }

  9. #9
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by umen242 View Post
    ok i did place it with one big main and it does work also .
    maybe the problem is in the includes . im using forward declaration here maybe this is problem also . i don't know
    what im trying to do here i can't give here the real code.
    i just need to make it some how work .
    as i said in my first post in my real app i need to pass to worker thread the ability to use function of the object that started the thread .
    Thanks
    A function that you pass to a thread MUST be a static function. There is no choice. Because the thread doesn't know the object the function belongs to, so it can not pass the hidden "this" argument that a non-static function requires. You have no choice here.

    Normally, thread functions take at least one argument that is usually a void pointer. As long as you know what you are doing, you can pass your object's address as the void pointer, and get it as an argument to your thread function. Something like this:
    Code:
    class A
    {
     public:
       static void ThreadFunction(void *p);
     private:
       void print(void) { std::cout << "Hello\n"; }
       void doThreadFunction(void) { print(); };
    }
    
    A a;
    
    void A::ThreadFunction(void *p)
    {
       A* ap = static_cast<A*>(p);
       p->doThreadFunction();
    }
    
    int main()
    {
        create_thread(... &a.ThreadFunction ...);
    }
    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  10. #10
    Banned master5001's Avatar
    Join Date
    Aug 2001
    Location
    Visalia, CA, USA
    Posts
    3,685
    I see what you are doing now that I am looking more carefully at the reference link again. Don't write code like that site was doing in that example.

  11. #11
    Registered User
    Join Date
    Mar 2008
    Posts
    58
    matsp can you please help to implement your code example in my code
    im trying to do this but i have problem to understand how can i invoke the member function from the TestMethod class.
    about the thread lts leave this aside . im will focus on the solution of invoking member function from different object
    Thanks

  12. #12
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    I'd rather spend my energy fixing your REAL code than the abhoration that is an example of HOW NOT TO DO THINGS.

    Show an example of what you REALLY want to do, and I'll help you.

    This works for me, based on your original code (but compressed into one file to make life easier for me, as I generally have a few dozen small projects in one directory, and it's hard enough without each project having 4 different "bits" to track):
    Code:
    #include <iostream>
    #include <stdio.h>
    #include <vector>
    #include <string>
    
    class TestClass
    {
    public :
        void add();
        void SayHelp(std::vector<std::string>* vv1);
          
    private: 
        int m_test;
    };
    
    typedef  void (TestClass::*FredMemFn)(std::vector<std::string>* vv);  
    
    class TestMethod 
    {
    public :
        void Init(TestClass& o, FredMemFn p,std::vector<std::string>* vv);
    private :
        TestClass* m_TestClass;
    
    };
    
    #define CALL_MEMBER_FN(object,ptrToMember)  ((object).*(ptrToMember))
    void callit(TestClass& o, FredMemFn p,std::vector<std::string>* vv)
    {
        CALL_MEMBER_FN(o,p)(vv);
    }
    
    void TestMethod::Init(TestClass& o, FredMemFn p,std::vector<std::string>* vv1) 
    {
        int h = vv1->size();
        callit(o,p,vv1);
    }
    
    
    void TestClass::SayHelp(std::vector<std::string>* vv)
    {
        std::cout << "Help" << std::endl;   
    }
    void TestClass::add()
    {
        std::vector<std::string> vv1;
        vv1.push_back("DDDD");
        TestMethod* testMethod = new TestMethod();
        FredMemFn p = &TestClass::SayHelp; 
        testMethod->Init(*this,p,&vv1);  
    }
    
    int main()
    {
        TestClass t;
        t.add();
    }
    Of course, it won't work with a thread function because you need to use static. But none of the above looks like anything that you would sensibly feed as a thread anyways, so I don't see the point of "converting it" to anythings else.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  13. #13
    Registered User
    Join Date
    Mar 2008
    Posts
    58
    what yo mean by "Show an example of what you REALLY want to do, and I'll help you. "
    you like to see real code ? of the application ?

  14. #14
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    No, it doesn't have to be (shouldn't be) a real application, but a small sample using thread calls. I don't want try to "fix" something cut'n'paste from a FAQ that show you HOW NOT to do things, and further there is no mention of what you want to use threads for in that source, so I have no idea what you are ACTUALLY trying to do in your thread.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Compiling sample DarkGDK Program
    By Phyxashun in forum Game Programming
    Replies: 6
    Last Post: 01-27-2009, 03:07 AM
  2. Undefined Reference Compiling Error
    By AlakaAlaki in forum C++ Programming
    Replies: 1
    Last Post: 06-27-2008, 11:45 AM
  3. Screwy Linker Error - VC2005
    By Tonto in forum C++ Programming
    Replies: 5
    Last Post: 06-19-2007, 02:39 PM
  4. Game Pointer Trouble?
    By Drahcir in forum C Programming
    Replies: 8
    Last Post: 02-04-2006, 02:53 AM
  5. Dikumud
    By maxorator in forum C++ Programming
    Replies: 1
    Last Post: 10-01-2005, 06:39 AM