如何将GTK+-2.0的信号、回调处理映射成类成员函数的调用

想将GTK+-2.0的信号、回调处理映射成类成员函数,然后我们就可以很简单的

将一个个GTK+2.0中的构件映射成类了,其实就是避开GTKMM那么复杂的东东。

 1 #ifndef __BASE_OBJECT_CLASS__
 2  #define __BASE_OBJECT_CLASS__
 3 
 4 #include <glib.h>
 5 #include <glib- object.h>
 6 
 7  #if 0
 8  // 函数指针转换,可以把一种类型的数据直接转换成第二种类型的数据
 9 template < class FuncPt1,  class FuncPt2>
10 inline FuncPt1 Func_Cast(FuncPt2 pt1)
11 {
12     union __TranPt1ToPt2
13     {
14         FuncPt2 pointer2;
15         FuncPt1 pointer1;
16     } __Tran = {pt1};
17      return __Tran.pointer1;
18 }
19  #endif
20 
21 #ifndef __GNUC__
22  #define SIGNAL_CALLBACK __cdcel
23  #else
24  #define SIGNAL_CALLBACK __attribute__((cdecl))
25  #endif
26 
27  class BaseObject
28 {
29  public:
30     BaseObject();
31      virtual ~BaseObject();
32 
33      /*  创建对象并绑定信号的接口  */
34      virtual gulong setupObject() =  0;
35 
36  protected:
37     typedef gulong (BaseObject::*CommonCallback)(GObject*instance, ...);
38 
39     typedef  struct tagOBJ_CALLBACK
40     {
41         BaseObject*     x_pThis;
42         CommonCallback  x_pCallback;
43         GObject*        x_pWidget;
44     } ObjectCallbackInfo;
45 
46     GObject*    x_pObject;
47 
48     gulong ConnectSignal(gpointer instance,  const gchar *detailed_signal, CommonCallback c_handler);
49 
50  private:
51     GSList* x_pObjectList;
52 
53      static gulong SignalProc( const ObjectCallbackInfo* lpObject, ...);
54 };
55 
56  #endif

 

 1 #include  " BaseObject.hpp "
 2 #include <stdarg.h>
 3 #include <stdio.h>
 4 
 5 BaseObject::BaseObject():x_pObject(NULL),x_pObjectList(NULL)
 6 {
 7 }
 8 
 9 BaseObject::~BaseObject()
10 {
11      /*  释放所有分配的ObjectToMemFunc空间  */
12     gpointer lpObj;
13     GSList* lpTempList = x_pObjectList;
14      while (NULL != lpTempList)
15     {
16          /*  如果非空  */
17         lpObj = g_slist_nth_data(lpTempList,  0);
18          if (NULL != lpObj)
19         {
20             g_free(lpObj);
21         }
22     
23         lpTempList = g_slist_next(lpTempList);
24     }
25      /*  删除列表  */
26      if (NULL != x_pObjectList)
27     {
28         g_slist_free(x_pObjectList);
29     }
30 }
31 
32 gulong BaseObject::ConnectSignal(gpointer instance, 
33                                   const gchar *detailed_signal,
34                                  CommonCallback c_handler)
35 {
36      /*  分配存放回调指针的空间  */
37     ObjectCallbackInfo* lpObject = (ObjectCallbackInfo*)g_malloc( sizeof(ObjectCallbackInfo));
38      if (NULL == lpObject)
39     {
40          return  0;
41     }
42     lpObject->x_pThis     =  this;
43     lpObject->x_pCallback = c_handler;
44     lpObject->x_pWidget   = (GObject*)instance;
45      /*  将信息保存在slist中  */
46     x_pObjectList = g_slist_append(x_pObjectList, lpObject);
47 
48      /*  注册信号回调  */
49      return g_signal_connect_swapped(instance, detailed_signal, 
50                                    (GCallback)&(BaseObject::SignalProc), (gpointer)lpObject);
51 }
52 
53 gulong BaseObject::SignalProc( const ObjectCallbackInfo* lpObject, ...)
54 {
55     va_list pArgList;
56     gulong ulRetcode;
57      struct reserve_arg { gulong ulReserver[ 20];} *pstTemp;
58     BaseObject* lpThis;
59     CommonCallback pCallBack;
60 
61      /*  收到信号时,先判断指针  */
62      if ( (NULL == lpObject) || (NULL == lpObject->x_pCallback ) || (NULL == lpObject->x_pWidget))
63     {
64          return  0;
65     }
66      /*  取出this指针及成员函数指针  */
67     va_start(pArgList, lpObject);
68     pstTemp = ( struct reserve_arg*)pArgList;
69     lpThis = lpObject->x_pThis;
70     pCallBack = lpObject->x_pCallback;
71     
72      /*  调用成员函数  */
73     ulRetcode = (lpThis ->*pCallBack)(lpObject->x_pWidget, *pstTemp);
74     
75     va_end(pArgList);
76     
77      return ulRetcode;
78 }

 使用几个关键技术点:

1.将对象指针、对象的成员函数指针及构件指针保存到对象的成员:一个简单列表中

2.静态成员函数指针作为实际的信号处理接口设置到GTK+-2.0的信号处理中

3.GTK+-2.0的信号处理设置采用g_signal_connect_swapped接口,则静态成员函数第一个参数就是第1步保存的列表指针数据

4.调用成员函数指针时,不考虑成员函数的参数个数,采用默认有20个UINT32的参数作为成员函数的参数,这里要求成员函数必须

是遵守C语言调用规范的,即必须是cdecl,因此声明函数必须为__cdecl

5.使用基类的成员函数指针来调用派生类的成员函数,这种行为已经在标准中声明是未定义的。

6.对于5,单一继承、多继承经验证,在GCC/VC上都通过了。但对于虚拟继承,无法支持,根因还在于虚拟继承的成员函数指针调用

方式完全不相同。

7.对于虚拟继承的成员函数指针调用,实现起来其实也应该不复杂,将BaseObject类进行拆分成Object与BaseObject,然后BaseObject

虚拟继承自Object,那么在生成调用代码时,应该就是能够支持虚拟继承的成员函数指针调用 -- 未验证

 

转载于:https://www.cnblogs.com/eaglexmw/archive/2013/05/02/3054876.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值