呵呵,今天学到一牛办法。

邹伟从网上找的,托管终于完美了。
原来的问题是无法托管给非静态函数,因为虽然可以取得函数指针,但是无法调用。
template <typename OT, typename PFT>
struct _wkMFPointer
{
};
template <typename OT,typename RT>
struct _wkMFPointer< OT, RT(*)() >
{
typedef RT (OT::*type)();
};
template <typename OT, typename RT, typename AT>
struct _wkMFPointer< OT, RT(*)(AT) >
{
typedef RT (OT::*type)(AT);
};
template <typename OT, typename RT, typename AT1, typename AT2>
struct _wkMFPointer< OT, RT(*)(AT1,AT2) >
{
typedef RT (OT::*type)(AT1,AT2);
};
template <typename OT, typename RT, typename AT1, typename AT2, typename AT3>
struct _wkMFPointer< OT, RT(*)(AT1,AT2,AT3) >
{
typedef RT (OT::*type)(AT1,AT2,AT3);
};

// 用于const函数
template <typename OT, typename PFT>
struct _wkCMFPointer
{
};
template <typename OT, typename RT>
struct _wkCMFPointer< OT, RT(*)() >
{
typedef RT (OT::*type)() const;
};
template <typename OT, typename RT, typename AT>
struct _wkCMFPointer< OT, RT(*)(AT) >
{
typedef RT (OT::*type)(AT) const;
};
template <typename OT, typename RT, typename AT1, typename AT2>
struct _wkCMFPointer< OT, RT(*)(AT1,AT2) >
{
typedef RT (OT::*type)(AT1,AT2) const;
};
template <typename OT, typename RT, typename AT1, typename AT2, typename AT3>
struct _wkCMFPointer< OT, RT(*)(AT1,AT2,AT3) >
{
typedef RT (OT::*type)(AT1,AT2,AT3) const;
};



typedef void(*ONEVENT)(WKObject* Sender,WKEventArgs* e);

class Event
{
public:
class Receiver{};
typedef _wkMFPointer<Receiver,ONEVENT>::type MFT;

Event(void* p,ONEVENT event)
{
Object = (Receiver*)p;
Function = event;
}
template<typename O>
Event(const O*p,typename _wkMFPointer<O,ONEVENT>::type fun)
{
Object = (Receiver*)p;
MFunction = (MFT)fun;
}
void operator()(WKObject* Sender,WKEventArgs* e)
{
if (Object)
{
(Object->*(MFunction))(Sender,e);
}
else
{
Function(Sender,e);
}
}
Receiver* Object;
union
{
ONEVENT Function;
MFT MFunction;
};
};

class B
{
public :
void OnClick(WKObject* Sender,WKEventArgs* e)
{
}
};

void OnClick(WKObject* Sender,WKEventArgs* e)
{
}
 
class A
{
public:
EventManage Click;
};

void main()
{
A a;
B b;
a.Click += Event(&b,&B::OnClick);
a.Click(NULL,NULL);
}
重点有两个,
第一个:
a.Click += Event(&b,&B::OnClick);

                template<typename O>
Event(const O*p,typename _wkMFPointer<O,ONEVENT>::type fun)
{
Object = (Receiver*)p;
MFunction = (MFT)fun;
}
传 入一个指针(const O*p),就可以得到p的类型(O,这个名字有点烂,呵呵),这个以前没有用过,不过听说早就支持了,哎,菜啊。传入一个函数指 针,就可以得到这个函数的类型,靠,编译器也太牛叉了。看来还是要知道函数指针到底是怎么实现的,要当一个牛叉的程序员还是要懂一些底层的东西,侯杰说的 很对。
第二个:
if (Object)
{
(Object->*(MFunction))(Sender,e);
}
else
{
Function(Sender,e);
}
解决了只能托管给静态函数的问题。原来只能这样调用:
else
{
Function(Sender,e);
}
呵呵,现在可以托管给任意类的任意函数,爽。
第一点由于现在的被托管函数都是固定两个参数的,所以没有用到。
呵呵,不过,解决了另一个问题,以前写的让脚本直接支持用宏声明的函数,用模板偏特化,靠,那叫一个累啊,而且参数个数不同宏就不同(虽然当时也觉得很恶心,但是没想到更好的解决办法,呵呵,其实是没想,不过想也不一定想的出来更好的)。现在好了,全部搞定。

posted on 2004-05-28 16:19  ChenA  阅读(318)  评论(0编辑  收藏  举报

导航