design woes ... confused on an implementation approach



 DEVELOP > c-Plus-Plus > design woes ... confused on an implementation approach

LINK TO THIS PAGE  


rating :  0   |  0


  Page 1 of 1

1

 
Topic: DEVELOP > c-Plus-Plus
User: ""
Date: 31 Jul 2005 08:26:08 PM
Object: design woes ... confused on an implementation approach
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
.

User: "Maxim Yegorushkin"

Title: Re: design woes ... confused on an implementation approach 01 Aug 2005 03:55:35 AM
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.
.
User: ""

Title: Re: design woes ... confused on an implementation approach 01 Aug 2005 09:29:50 AM
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.
.
User: "Maxim Yegorushkin"

Title: Re: design woes ... confused on an implementation approach 01 Aug 2005 09:50:58 AM
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.
.
User: ""

Title: Re: design woes ... confused on an implementation approach 01 Aug 2005 06:05:19 PM
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?
.
User: "Maxim Yegorushkin"

Title: Re: design woes ... confused on an implementation approach 02 Aug 2005 01:30:41 AM
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);
// ...
}
.






  Page 1 of 1

1

 


Related Articles
 

NEWER

pg.1232     pg.940     pg.716     pg.544     pg.412     pg.311     pg.234     pg.175     pg.130     pg.96     pg.70     pg.50     pg.35     pg.24     pg.16     pg.10     pg.6     pg.3     pg.1

OLDER