design woes ... confused on an implementation approach

Discussion in 'C++' started by ma740988@pegasus.cc.ucf.edu, Aug 1, 2005.

  1. Guest

    Select parameters in a vendors API file is as follows:

    #ifdef __cplusplus
    typedef void (*VOIDFUNCPTR)(...); /* ptr to function returning void
    */
    #else
    typedef void (*VOIDFUNCPTR)(); /* ptr to function returning void
    */
    #endif /* __cplusplus */

    enum CAUSE { CHAN0_COMPLETE, CHAN0_MISS, CHAN0_HIT, CHAN0_ISM };
    bool IntConnect( CAUSE c, VOIDFUNCPTR p, int idx, int jdx);
    // end vendors file

    The member function IntConnect that takes a cause; a VOIDFUNCPTR; and
    a two integer variables.

    The basic premise: You'll pass your desired - static/global - member
    function + cause, etc .. to the vendors IntConnect member function.

    To bypass the 'procedural approach' I have a class transfer that takes
    a map and a function pointer.

    class transfer {
    static std::auto_ptr<cb_base> user_cb;
    map<CAUSE, VOIDFUNCPTR> myMap;
    static void callback_mem_func1(...) {
    // call user function passed in via connect_interrupt
    cb_base &cb = *user_cb;
    }
    static void callback_mem_func2(...) {
    // call user function passed in via connect_interrupt
    cb_base &cb = *user_cb;
    }
    /// more

    public:
    transfer() {
    myMap[CHAN0_COMPLETE] = &transfer::callback_mem_func1;
    myMap[CHAN0_MISS] = &transfer::callback_mem_func2;
    // more
    }

    template <typename T>
    bool connect_interrupt(
    CAUSE c,
    int param1,
    int param2,
    T& t,
    void (T::*f)(...) ) )
    {
    map<CAUSE, VOIDFUNCPTR>::iterator it = myMap.begin();
    for (; it != myMap.end(); ++it)
    {
    if ( it->first == c )
    {
    bool success = IntConnect(
    (*it).first,
    (*it).second,
    param1,
    param2
    );

    if ( success ) {
    user_cb.reset(new cb_derived<T>(t, f));
    }
    break;
    }
    } // end for
    };
    With this approach I'll register with IntConnect a static member
    function. The static member function will - in turn - call user
    desired member function.

    At issue: The current approach to user_cb WONT work. I need to have
    vector or something similar .. This way within the member functions
    callback_mem_func1, etc. I could do:

    void callback_mem_func1(...) {
    // call user function passed in via connect_interrupt
    cb_base &cb = *user_cb[0]; // <<<<NOTE HERE>>>
    }
    void callback_mem_func2(...) {
    // call user function passed in via connect_interrupt
    cb_base &cb = *user_cb[1]; // <<<<NOTE HERE>>>
    }
    or ... I'm open to a re-design worse case.

    // cb_base:

    # include <iostream>
    # include <memory>
    # include <string>

    using namespace std;
    class cb_base
    {
    public:
    virtual void operator()(...) const {};
    virtual ~cb_base() = 0;
    };

    inline cb_base::~cb_base() {}

    template <typename T>
    class cb_derived : public cb_base
    {
    public:
    typedef void (T::*F)(...);
    cb_derived( T& t, F f) : t_(&t), f_(f) {}
    void operator()(...) const
    {
    (t_->*f_)();
    }

    private:
    T* t_;
    F f_;
    };

    template <typename T>
    cb_derived<T> make_callback (T& t, void (T::*f)(...) )
    {
    return cb_derived<T>(t, f);
    }

    template <class T>
    std::auto_ptr<cb_base> new_callback(T& t, void (T::*f)(...))
    {
    return std::auto_ptr<cb_base>(new cb_derived<T>(t, f));
    }


    Thanks in advance
     
    , Aug 1, 2005
    #1
    1. Advertising

  2. wrote:
    > Select parameters in a vendors API file is as follows:
    >
    > #ifdef __cplusplus
    > typedef void (*VOIDFUNCPTR)(...); /* ptr to function returning void
    > */
    > #else
    > typedef void (*VOIDFUNCPTR)(); /* ptr to function returning void
    > */
    > #endif /* __cplusplus */
    >
    > enum CAUSE { CHAN0_COMPLETE, CHAN0_MISS, CHAN0_HIT, CHAN0_ISM };
    > bool IntConnect( CAUSE c, VOIDFUNCPTR p, int idx, int jdx);
    > // end vendors file


    Are you sure that VOIDFUNCPTR takes no arguments before the ellipsis?
    Because as it's declared now there is no way to get arguments from
    inside VOIDFUNCPTR callback.
     
    Maxim Yegorushkin, Aug 1, 2005
    #2
    1. Advertising

  3. Guest

    I'm sure. That is the way VOIDFUNCPTR is declared. It was a surprise
    to me when I encountered it. I never understood the need for the
    ellipsis.
     
    , Aug 1, 2005
    #3
  4. wrote:
    > I'm sure. That is the way VOIDFUNCPTR is declared. It was a surprise
    > to me when I encountered it. I never understood the need for the
    > ellipsis.


    Then it seems to be no way to pass any data to the callback, the
    callback has to operate on global data.
     
    Maxim Yegorushkin, Aug 1, 2005
    #4
  5. Guest

    Yeah but the more important questions is what's teh workaround for
    'user_cb'?. user_cb needs to reflect a list/vector or .......... How
    would you achieve this?
     
    , Aug 2, 2005
    #5
  6. wrote:
    > Yeah but the more important questions is what's teh workaround for
    > 'user_cb'?. user_cb needs to reflect a list/vector or .......... How
    > would you achieve this?


    I'd do something along these lines:

    typedef void (*VOIDFUNCPTR)();

    enum CAUSE { CHAN0_COMPLETE, CHAN0_MISS, CHAN0_HIT, CHAN0_ISM };
    bool IntConnect( CAUSE c, VOIDFUNCPTR p, int idx, int jdx);

    template<int N> struct int_ {};

    template<int N>
    void the_callback(int_<N>); // implement it
    // alternatively
    // void the_callback(int_<CHAN0_COMPLETE>);
    // void the_callback(int_<CHAN0_MISS>);

    template<int N>
    void callback_thunk()
    {
    the_callback(int_<N>());
    }

    void f()
    {
    IntConnect(CHAN0_COMPLETE, callback_thunk<CHAN0_COMPLETE>, 0, 0);
    IntConnect(CHAN0_MISS, callback_thunk<CHAN0_MISS>, 0, 0);
    // ...
    }
     
    Maxim Yegorushkin, Aug 2, 2005
    #6
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Mr Gordonz

    Advice on design approach and principles

    Mr Gordonz, Aug 4, 2003, in forum: ASP .Net
    Replies:
    1
    Views:
    374
    Steve C. Orr, MCSD
    Aug 4, 2003
  2. Bijoy Naick
    Replies:
    1
    Views:
    436
    Jeffrey Palermo [MCP]
    Nov 17, 2004
  3. Replies:
    4
    Views:
    429
  4. Replies:
    11
    Views:
    4,783
    Juha Nieminen
    Jan 28, 2008
  5. darpan6aya

    Confused approach to Pyinstaller

    darpan6aya, Jun 29, 2013, in forum: Python
    Replies:
    0
    Views:
    131
    darpan6aya
    Jun 29, 2013
Loading...

Share This Page