registering class methods as C style callbacks

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • noone@all.com

    registering class methods as C style callbacks

    consider the following problem:

    You have a C style library and API that uses callbacks to implement
    functionality. Examples of this are X11 API, OpenGL/GLUT...The List goes
    on.

    The power of virtuals in C++ leads us to want to implement a framework
    where those callbacks are simply overriden virtual methods in a derived
    class. So...

    struct A {
    A() { ::set_timerrout ine(timerroutin e); }
    ~A() { ::clear_timerro utine(); }
    void timerroutine() { action(); }
    virtual void action()=0;
    };

    struct B: public A {
    B(): A() {}
    action() { // do something relevant here }
    };

    B myTimerObject;


    On the surface we would expect that registering the class method
    timerroutine in the constructor for A would cause B::action() to be
    invoked but I've not found a way to cast a class method to a generic
    function pointer as is expected in C style callbacks.

    How can I accomplish this without the extremely ugly overhead of
    "referencin g static object pointers in a C style timerroutine() that is
    not itself a class method?"

    The idea/requirement is to have a framework that can exist solely in a
    header file and thus serve as a template.

    -Rob


  • Julián Albo

    #2
    Re: registering class methods as C style callbacks

    noone@all.com wrote:
    On the surface we would expect that registering the class method
    timerroutine in the constructor for A would cause B::action() to be
    invoked but I've not found a way to cast a class method to a generic
    function pointer as is expected in C style callbacks.
    A cast is not enough. To use a member function you need both the function
    and an object.

    Systems with callbacks usually provide a way to pass a pointer to the
    function that sets the callback, and pass this pointer value when calling
    the callback function. You just need to use a pointer to a base class, and
    use it to call the virtual function you want.

    --
    Salu2

    Comment

    • noone@all.com

      #3
      Re: registering class methods as C style callbacks

      On Mon, 17 Jul 2006 21:22:00 +0200, Julián Albo wrote:
      noone@all.com wrote:
      >
      >On the surface we would expect that registering the class method
      >timerroutine in the constructor for A would cause B::action() to be
      >invoked but I've not found a way to cast a class method to a generic
      >function pointer as is expected in C style callbacks.
      >
      A cast is not enough. To use a member function you need both the function
      and an object.
      >
      Systems with callbacks usually provide a way to pass a pointer to the
      function that sets the callback, and pass this pointer value when calling
      the callback function. You just need to use a pointer to a base class, and
      use it to call the virtual function you want.
      Either I'm not understanding your explanation or you don't understand my
      problem fully: maybe a bit of both. registering a callback simply uses a
      function pointer (ptr*)() and since class methods are not really function
      pointers they cannot be directly registered in APIs that use C style
      callbacks. I need a way of registering them that does NOT require static
      pointers, or global C functions to get around the function pointer
      problem. this solution MUST be fully implementable in a header file so
      that it can serve as a template.


      Comment

      • Julián Albo

        #4
        Re: registering class methods as C style callbacks

        noone@all.com wrote:
        Either I'm not understanding your explanation or you don't understand my
        problem fully: maybe a bit of both. registering a callback simply uses a
        function pointer (ptr*)() and since class methods are not really function
        pointers they cannot be directly registered in APIs that use C style
        callbacks. I need a way of registering them that does NOT require static
        pointers, or global C functions to get around the function pointer
        problem. this solution MUST be fully implementable in a header file so
        that it can serve as a template.
        The fact that you want it does not make it possible. If you want to use a
        non static member function you need a way to provide an object. If the
        callback style does not allow it, you need to use a global variable or some
        other workaround.

        --
        Salu2

        Comment

        • Howard Gardner

          #5
          Re: registering class methods as C style callbacks

          // This should see you on your way.

          #include <cstddef>
          #include <ostream>
          using namespace std;

          struct demo
          {
          void
          func()
          {
          cout << "called" << endl;
          }
          };

          template< typename xObj, void (xObj::*xPtr)() >
          struct
          bound_func
          {
          static
          xObj
          obj;

          static
          void
          call()
          {
          (obj.*xPtr)();
          }
          };

          template< typename xObj, void (xObj::*xPtr)() >
          xObj
          bound_func< xObj, xPtr >::obj;

          int
          main()
          {
          typedef bound_func< demo, &demo::func tBound;
          tBound::call();
          // &tBound::cal l should be suitable for a callback
          }

          Comment

          • Jon Clements

            #6
            Re: registering class methods as C style callbacks


            Julián Albo wrote:
            noone@all.com wrote:
            >
            Either I'm not understanding your explanation or you don't understand my
            problem fully: maybe a bit of both. registering a callback simply uses a
            function pointer (ptr*)() and since class methods are not really function
            pointers they cannot be directly registered in APIs that use C style
            callbacks. I need a way of registering them that does NOT require static
            pointers, or global C functions to get around the function pointer
            problem. this solution MUST be fully implementable in a header file so
            that it can serve as a template.
            >
            The fact that you want it does not make it possible. If you want to use a
            non static member function you need a way to provide an object. If the
            callback style does not allow it, you need to use a global variable or some
            other workaround.
            >
            --
            Salu2
            My C++ is a little rusty (and I don't have a compiler handy to try) -
            so ignore me if I'm talking dribble. Is it possible that mem_fun_ref
            can be used to create a unary function object, which is then passed to
            the callback? But like I say, not sure that would work, or indeed, if
            it's safe. However, could throw a possible angle on things (or not...)


            Jon.

            Comment

            • Victor Bazarov

              #7
              Re: registering class methods as C style callbacks

              Jon Clements wrote:
              [..]
              My C++ is a little rusty (and I don't have a compiler handy to try) -
              so ignore me if I'm talking dribble. Is it possible that mem_fun_ref
              can be used to create a unary function object, which is then passed to
              the callback? But like I say, not sure that would work, or indeed, if
              it's safe. However, could throw a possible angle on things (or not...)
              Any templates from C++ Standard Library (and objects derived therefrom)
              are useless when C callbacks are concerned). C has no idea about any
              "function objects".

              V
              --
              Please remove capital 'A's when replying by e-mail
              I do not respond to top-posted replies, please don't ask


              Comment

              • Julián Albo

                #8
                Re: registering class methods as C style callbacks

                Jon Clements wrote:
                My C++ is a little rusty (and I don't have a compiler handy to try) -
                so ignore me if I'm talking dribble. Is it possible that mem_fun_ref
                can be used to create a unary function object, which is then passed to
                the callback? But like I say, not sure that would work, or indeed, if
                it's safe. However, could throw a possible angle on things (or not...)
                mem_fun_ref has no magic, it just creates objects that pass references to
                the object you pass and the member function you want to use. The problem is
                the same as if you write a specific class for the task.

                What specific problem are you trying to solve? Maybe there are other ways to
                do the task.

                --
                Salu2

                Comment

                • Jon Clements

                  #9
                  Re: registering class methods as C style callbacks


                  Victor Bazarov wrote:
                  Any templates from C++ Standard Library (and objects derived therefrom)
                  are useless when C callbacks are concerned). C has no idea about any
                  "function objects".
                  Surely though - if it just dereferences the function object (or pointer
                  to it maybe?), it doesn't even need to know it's a function object?

                  Jon.

                  Comment

                  • Jon Clements

                    #10
                    Re: registering class methods as C style callbacks


                    Julián Albo wrote:
                    mem_fun_ref has no magic, it just creates objects that pass references to
                    the object you pass and the member function you want to use. The problem is
                    the same as if you write a specific class for the task.
                    >
                    What specific problem are you trying to solve? Maybe there are other waysto
                    do the task.
                    Was just wondering if it was a possible solution for the OP. However, I
                    think Victor and yourself have enlightened me to the fact, this
                    wouldn't be a solution.

                    Just seemed to make sense at the time of generating a function object
                    and passing the address of that to the callback....

                    Cheers

                    Jon

                    Comment

                    • Howard Gardner

                      #11
                      Re: registering class methods as C style callbacks

                      Jon Clements wrote:
                      Victor Bazarov wrote:
                      >
                      >Any templates from C++ Standard Library (and objects derived therefrom)
                      >are useless when C callbacks are concerned). C has no idea about any
                      >"function objects".
                      >
                      Surely though - if it just dereferences the function object (or pointer
                      to it maybe?), it doesn't even need to know it's a function object?
                      >
                      Jon.
                      >
                      It also passes a pointer to the object to the function (its the "this"
                      pointer). That's the problem.

                      a.func() is kindof the same as func(&a), not func().

                      Comment

                      • Julián Albo

                        #12
                        Re: registering class methods as C style callbacks

                        Jon Clements wrote:
                        >mem_fun_ref has no magic, it just creates objects that pass references to
                        >the object you pass and the member function you want to use. The problem
                        >is the same as if you write a specific class for the task.
                        >>
                        >What specific problem are you trying to solve? Maybe there are other ways
                        >to do the task.
                        >
                        Was just wondering if it was a possible solution for the OP. However, I
                        Sorry, 'you' intended to be 'the OP'

                        --
                        Salu2

                        Comment

                        • noone

                          #13
                          Re: registering class methods as C style callbacks

                          On Mon, 17 Jul 2006 20:02:47 +0000, Howard Gardner wrote:
                          template< typename xObj, void (xObj::*xPtr)() >
                          struct
                          bound_func
                          {
                          static
                          xObj
                          obj;
                          >
                          static
                          void
                          call()
                          {
                          (obj.*xPtr)();
                          }
                          };

                          thanks, but wouldn't

                          static xObj obj

                          also need to be defined in a source file as well as being declared in the
                          template header as you show above? the requirement of a definition in a
                          related source file is what I'm trying to get away from.


                          Comment

                          • Victor Bazarov

                            #14
                            Re: registering class methods as C style callbacks

                            noone wrote:
                            On Mon, 17 Jul 2006 20:02:47 +0000, Howard Gardner wrote:
                            >
                            >template< typename xObj, void (xObj::*xPtr)() >
                            > struct
                            > bound_func
                            > {
                            > static
                            > xObj
                            > obj;
                            >>
                            > static
                            > void
                            > call()
                            > {
                            > (obj.*xPtr)();
                            > }
                            > };
                            >
                            >
                            thanks, but wouldn't
                            >
                            static xObj obj
                            >
                            also need to be defined in a source file as well as being declared in
                            the template header as you show above? the requirement of a
                            definition in a related source file is what I'm trying to get away
                            from.
                            Since it's a member of a class template, it's a template itself. You
                            don't need to define it in a source file, but you need to define it
                            outside the class template, in the same header. When you use it, the
                            static data member will be first *instantiated* and then *initialised*
                            according to your "definition " statement. You needn't worry about
                            putting it in a source file somewhere.

                            V
                            --
                            Please remove capital 'A's when replying by e-mail
                            I do not respond to top-posted replies, please don't ask


                            Comment

                            Working...