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. Class member function as call back

Class member function as call back

Scheduled Pinned Locked Moved C / C++ / MFC
helpquestion
12 Posts 4 Posters 2 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.
  • N NoviceEx

    Maybe someone will be able to help me with this quite complex problem. First of all I have control initialization function which requires callback

    typedef int (*callback_fnc)(HWND, int, ...);
    my_init_control(HWND hwnd, callback_fnc cb, int flags);

    I have few classes:

    Class A
    {
    public:
    ...
    private:
    int var1;
    }

    Class B: public A
    {
    public:
    ...
    void init();
    int proc(HWND hwnd, int msg, ...); // it uses var1 and var2
    ...
    private:
    int var2;
    }

    I need to init control and I need to use class B function proc as callback function. Tried to use it that way but it does not work that way.

    void B::init()
    {
    my_init_control(itemHwnd, B::proc, 0);
    }

    Also I have tried that way

    my_init_control(itemHwnd, boost::bind(&B::proc, this), 0);

    but it does not work either. Tried to google but cannot find samples close to my case. So question is what should I need to do in order to use function

    B::proc()

    as callback in

    B::init()

    .

    L Offline
    L Offline
    Lost User
    wrote on last edited by
    #2

    NoviceEx wrote:

    but it does not work either.

    Exactly what does that mean? Does it compile, does it get called in your code but fail in some way, does it not get called, are some of the parameters not passed correctly ... ? It would help if you showed the actual code that is supposed to work (and please use <pre> tags round it so it is readable) and explained where any failure happens.

    N 1 Reply Last reply
    0
    • L Lost User

      NoviceEx wrote:

      but it does not work either.

      Exactly what does that mean? Does it compile, does it get called in your code but fail in some way, does it not get called, are some of the parameters not passed correctly ... ? It would help if you showed the actual code that is supposed to work (and please use <pre> tags round it so it is readable) and explained where any failure happens.

      N Offline
      N Offline
      NoviceEx
      wrote on last edited by
      #3

      I need to use class member function as callback, because "callback" has to have access to some variables of the class in order to operate.

      L 1 Reply Last reply
      0
      • N NoviceEx

        I need to use class member function as callback, because "callback" has to have access to some variables of the class in order to operate.

        L Offline
        L Offline
        Lost User
        wrote on last edited by
        #4

        Yes, we already know that; please edit your question and make clear what the actual problem is with your code.

        1 Reply Last reply
        0
        • N NoviceEx

          Maybe someone will be able to help me with this quite complex problem. First of all I have control initialization function which requires callback

          typedef int (*callback_fnc)(HWND, int, ...);
          my_init_control(HWND hwnd, callback_fnc cb, int flags);

          I have few classes:

          Class A
          {
          public:
          ...
          private:
          int var1;
          }

          Class B: public A
          {
          public:
          ...
          void init();
          int proc(HWND hwnd, int msg, ...); // it uses var1 and var2
          ...
          private:
          int var2;
          }

          I need to init control and I need to use class B function proc as callback function. Tried to use it that way but it does not work that way.

          void B::init()
          {
          my_init_control(itemHwnd, B::proc, 0);
          }

          Also I have tried that way

          my_init_control(itemHwnd, boost::bind(&B::proc, this), 0);

          but it does not work either. Tried to google but cannot find samples close to my case. So question is what should I need to do in order to use function

          B::proc()

          as callback in

          B::init()

          .

          CPalliniC Offline
          CPalliniC Offline
          CPallini
          wrote on last edited by
          #5

          As far as I know, you cannot do that. That is you cannot pass the result of bind on a class member function as a C-style callback. If you cannot change the prototype of my_init_control then you have to use a workaround (e.g. write the callback as a standard function).

          In testa che avete, signor di Ceprano?

          1 Reply Last reply
          0
          • N NoviceEx

            Maybe someone will be able to help me with this quite complex problem. First of all I have control initialization function which requires callback

            typedef int (*callback_fnc)(HWND, int, ...);
            my_init_control(HWND hwnd, callback_fnc cb, int flags);

            I have few classes:

            Class A
            {
            public:
            ...
            private:
            int var1;
            }

            Class B: public A
            {
            public:
            ...
            void init();
            int proc(HWND hwnd, int msg, ...); // it uses var1 and var2
            ...
            private:
            int var2;
            }

            I need to init control and I need to use class B function proc as callback function. Tried to use it that way but it does not work that way.

            void B::init()
            {
            my_init_control(itemHwnd, B::proc, 0);
            }

            Also I have tried that way

            my_init_control(itemHwnd, boost::bind(&B::proc, this), 0);

            but it does not work either. Tried to google but cannot find samples close to my case. So question is what should I need to do in order to use function

            B::proc()

            as callback in

            B::init()

            .

            L Offline
            L Offline
            Lost User
            wrote on last edited by
            #6

            Try this, noting that Class (with capital C) is incorrect, it should be class. Also that B::proc needs to be static.

            #include #include typedef int (*callback_fnc)(int);
            void my_init_control(callback_fnc cb, int flags)
            {
            cb(flags);
            }

            class B
            {
            public:
            void init()
            {
            my_init_control(&B::proc, 0);
            }

            static int proc(int msg) // it uses var1 and var2
            {
                printf("This is message number %d\\n", msg);
                return 0;
            }
            

            };

            int main(
            )
            {
            B bobj;
            bobj.init();

            return 0;
            

            }

            N 1 Reply Last reply
            0
            • L Lost User

              Try this, noting that Class (with capital C) is incorrect, it should be class. Also that B::proc needs to be static.

              #include #include typedef int (*callback_fnc)(int);
              void my_init_control(callback_fnc cb, int flags)
              {
              cb(flags);
              }

              class B
              {
              public:
              void init()
              {
              my_init_control(&B::proc, 0);
              }

              static int proc(int msg) // it uses var1 and var2
              {
                  printf("This is message number %d\\n", msg);
                  return 0;
              }
              

              };

              int main(
              )
              {
              B bobj;
              bobj.init();

              return 0;
              

              }

              N Offline
              N Offline
              NoviceEx
              wrote on last edited by
              #7

              I cannot modify "my_init_control()" Maybe someone knows how can it be done using boost::bind ?

              CPalliniC L 2 Replies Last reply
              0
              • N NoviceEx

                I cannot modify "my_init_control()" Maybe someone knows how can it be done using boost::bind ?

                CPalliniC Offline
                CPalliniC Offline
                CPallini
                wrote on last edited by
                #8

                As I told before, I am afraid you cannot (see, for instance c++ - Is it possible to bind() *this to class member function to make a callback to C API - Stack Overflow[^]). If you cannot modify my_init_control the you have to provide a compliant (that is a C-like) callback. In such a callback you might do the dirty work of accessing the class methods.

                In testa che avete, signor di Ceprano?

                1 Reply Last reply
                0
                • N NoviceEx

                  I cannot modify "my_init_control()" Maybe someone knows how can it be done using boost::bind ?

                  L Offline
                  L Offline
                  Lost User
                  wrote on last edited by
                  #9

                  According to Chapter 1. Boost.Bind - 1.66.0[^] it can be done. You need to explain in more detail what happens when you try it.

                  CPalliniC 1 Reply Last reply
                  0
                  • L Lost User

                    According to Chapter 1. Boost.Bind - 1.66.0[^] it can be done. You need to explain in more detail what happens when you try it.

                    CPalliniC Offline
                    CPalliniC Offline
                    CPallini
                    wrote on last edited by
                    #10

                    I think the OP cannot. Consider the following piece of code.

                    #include #include using namespace std;

                    typedef void (*Callback)(int );

                    void invoke( Callback cb) { cb(5); }

                    void foo(int i) { cout << (i*2) << "\n";}

                    int main()
                    {
                    foo(3); // of course you ca do this

                    invoke(foo); // you can do this too

                    auto bf = std::bind(foo, placeholders::_1);
                    bf(7); // working bind

                    std::bind(foo, 9)(); // you can even do this!

                    invoke( std::bind(foo, placeholders::_1)); //<-- this doesn't compile, game over, you cannot do this
                    }

                    The last call is not allowed due to type mismatch between the bind return value and the C-like callback (I believe you might try similar code with boost).

                    In testa che avete, signor di Ceprano?

                    L 1 Reply Last reply
                    0
                    • CPalliniC CPallini

                      I think the OP cannot. Consider the following piece of code.

                      #include #include using namespace std;

                      typedef void (*Callback)(int );

                      void invoke( Callback cb) { cb(5); }

                      void foo(int i) { cout << (i*2) << "\n";}

                      int main()
                      {
                      foo(3); // of course you ca do this

                      invoke(foo); // you can do this too

                      auto bf = std::bind(foo, placeholders::_1);
                      bf(7); // working bind

                      std::bind(foo, 9)(); // you can even do this!

                      invoke( std::bind(foo, placeholders::_1)); //<-- this doesn't compile, game over, you cannot do this
                      }

                      The last call is not allowed due to type mismatch between the bind return value and the C-like callback (I believe you might try similar code with boost).

                      L Offline
                      L Offline
                      Lost User
                      wrote on last edited by
                      #11

                      Thanks for that; I looked at the boost documentation and it sort of implied that it could be done. But as I am new to this I probably misunderstood.

                      1 Reply Last reply
                      0
                      • N NoviceEx

                        Maybe someone will be able to help me with this quite complex problem. First of all I have control initialization function which requires callback

                        typedef int (*callback_fnc)(HWND, int, ...);
                        my_init_control(HWND hwnd, callback_fnc cb, int flags);

                        I have few classes:

                        Class A
                        {
                        public:
                        ...
                        private:
                        int var1;
                        }

                        Class B: public A
                        {
                        public:
                        ...
                        void init();
                        int proc(HWND hwnd, int msg, ...); // it uses var1 and var2
                        ...
                        private:
                        int var2;
                        }

                        I need to init control and I need to use class B function proc as callback function. Tried to use it that way but it does not work that way.

                        void B::init()
                        {
                        my_init_control(itemHwnd, B::proc, 0);
                        }

                        Also I have tried that way

                        my_init_control(itemHwnd, boost::bind(&B::proc, this), 0);

                        but it does not work either. Tried to google but cannot find samples close to my case. So question is what should I need to do in order to use function

                        B::proc()

                        as callback in

                        B::init()

                        .

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

                        boost::bind returns a function object, not a C function. It may behave like a function pointer, but these types are different, and the compiler won't be able to match the function argument list with a function object as the second argument. The problem you describe cannot be solved with the limitations you've set. Clearly, part of the limitations are of your own making and need to be revised. To understand that, you just need to think about the flow of control: 1. from your code you set up a callback mechanism that is supposed to call your callback function 2. then you call a function outside of your code 3. At some point this outside function calls your callback function, passing along some data 4. Your callback function is called. the only data it has are the function arguments it got passed from it's calling function. At this point it is entirely out of context from the rest of your application and doesn't know about any of your B objects that you may have created. If the calling function doesn't know about Bs, then the callback function cannot know about them either. It is impossible to process anything dependend on some B member variables in the callback function, unless you pass these variables all the way from step 1 through step 4! Unfortunately the code in step 3 is outside your control - therefore this is impossible. Or it wouldbe impossible if you insist on passing along a reference to some B object: the caller doesn't know about that class! There are only two solutions that may work: 1. the library you are using lets you pass along additional data to the callback setup which then will be passed to the callback invocation. If so, you could just pass along the values of var1 and var2. 2. If the above isn't possible, the only alternative I see is to use global variables to store the state of B or just its member variables. Of course. the premise that your callback absolutely needs to know your B object may have been wrong! Time to think about how you intended to use this callback mechanism!

                        GOTOs are a bit like wire coat hangers: they tend to breed in the darkness, such that where there once were few, eventually there are many, and the program's architecture collapses beneath them. (Fran Poretto)

                        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