Okay all. I have been looking at the ideas that you have posted here, and spent time experimenting. And now I think I might have a working solution. I won't mark this thread solved just yet. I'll give you some time to see what you think.
Note 1) The code here is only to show a method to do what I need. The actual application is much more complicated to show everything here.
Note 2) As per above, I left out all of the dictionary functionality here, since it is not relevant to the solution.
So here's the code:
d.h (defines base class and possible derived classes)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49
|
#ifndef X_H
#define X_H
class D;
using func_t = void (D::*)(void*);
typedef struct
{
const char* key;
D* pd;
func_t f;
}d_info;
class D
{
public:
D();
~D();
void add_func(const char* key ,func_t f);
static d_info *get_info(const char*key);
static void stat_dofunc(const char* k, void* data);
protected:
};
class D1 : public D
{
public:
D1();
~D1();
void f11(void* v){};
void f12(void* v){};
};
class D2 : public D
{
public:
D2();
~D2();
void f21(void* v){};
void f22(void* v){};
};
#endif
| |
d.cpp (the class implentantions)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
|
#include "D.h"
D::D(){};
D::~D(){};
void
D::add_func(const char* key func_t f){
d_info *pdi = new d_info;
pdi->f = f;
pdi->key = key;
pdi->pd = this;
// insert pdi into dict. (not shown here)
};
d_info*
D::get_info(const char* key){
d_info *pd; // = find info in dict. with key (not shown here)
return pd;
}
void
D::stat_dofunc(const char* k, void* data)
{
d_info *pdi = get_info(k);
((pdi->pd)->*(pdi->f))(data);
};
/* "add_func" calls could be done somewhere else
in code. this is just for convenience */
D1::D1(){
add_func("d11", &D1::f11);
add_func("d12", &D1::f12);
};
D1::~D1(){};
D2::D2(){
add_func("d21", &D2::f21);
add_func("d22", &D2::f22);
};
D2::~D2(){};
| |
main.cpp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
|
#include "D.h"
int main()
{
D1 x1, x11;
D1* px1=&x1;
D2 x2;
D2* px2=&x1;
void *v;
// do callbacks ()
D::stat_dofunc("d11", v); // will do x1.f11(v)
D::stat_dofunc("d12", v); // will do x1.f12(v)
D::stat_dofunc("d21", v); // will do x2.f21(v)
D::stat_dofunc("d22", v); // will do x2.f22(v)
// or maybe:
x11.add_func("do_d11", &D1::f11);
D::stat_dofunc("do_d11", v); // x11.f11(v)
}
| |
The trick here is the
d_info struct
. It saves a pointer to the actual instantiated object, which also provides implicitly the derived class type, and also a pointer to the appropriate class member and its class type. With that info, the static
stat_dofunc
can use smart pointers to the right class object, and the right class member function. Voila!
All of this is for (as mentioned previously) using a 3rd party "C" callback. It requires a pointer to a function that it calls at the appropriate time (only passing a string along as data). The static
stat_dofunc
is that function, that can be called from a "C" program library.
Comments?