您的位置:首页 > 其它

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

2013-05-17 14:21 549 查看
#ifndef __OBJECT_ORIENTED_C__
#define __OBJECT_ORIENTED_C__

#ifdef __cplusplus
extern "C" {
#endif

/* ========================================================================  */
/* 这一区块定义下面用到的一些名字组成宏 */
/* 类方法名字拼接 */
#define METHOD(class, method)               class##_##method
/* 类方法的类型的名字拼接 */
#define METHOD_TYPE(class, method)          __##class##_##method##_typedef__
/* 类的虚函数表结构的名字拼接 */
#define VTBL_STRU_NAME(class)               __##class##_v_func_tbl__
/* 类的虚函数在虚函数表中的位置的名字拼接 */
#define VTBL_FUNC_PTR_NAME(class, func)     __##class##_fp_##func##_offset__
/* 类的虚函数表实体的名字拼接 */
#define VTBL_ENTITY_NAME(class)             __##class##_vtable_array__
/* 类的虚函数表实体初始化函数的名字拼接 */
#define VTBL_ENTITY_INIT_METHOD(class)      __##class##_class_vtable_init__
/* 类的虚函数表实体是否初始化OK的名字拼接 */
#define VTBL_ENTITY_IS_INIT_FLAG(class)     __##class##_class_vtable_is_init__
/* 类的虚函数表实体初始化结构变量的名字拼接 */
#define VTBL_ENTITY_INIT_STRU_VAR(class)    class##_class_vtable_init_info
/* 获取类的虚函数表初始化函数的指针 */
#define VTBL_ENTITY_INIT_METHOD_PTR(class)  ( VTBL_ENTITY_INIT_STRU_VAR(class) . vtable_init_method)
/* ========================================================================  */

/* ========================================================================  */
/* 创建接口 */
#define new(class)                   METHOD(class, create)()
/* 释放接口 */
#define delete(class, object)        METHOD(class, destory)(object)
/* ========================================================================  */

/* ========================================================================  */
/* 类声明的开始宏 */
#define BEGIN_CLASS(class)                                          \
struct class;                                                   \
typedef struct class class;                                     \
struct VTBL_STRU_NAME(class);                                   \
extern class_vtable_init VTBL_ENTITY_INIT_STRU_VAR(class);      \
class * METHOD(class, create)(void);                            \
int  METHOD(class, constructor)(class* this);                   \
void METHOD(class, destory)(class* this);                       \
int  METHOD(class, destructor)(class* this);                    \
struct class

/* 继承自父类的声明 */
#define INHERITED_PARENT(p_class)                           \
p_class parent

/* 类中的虚函数声明开始宏 */
#define BEGIN_V_METHOD_DEFINE(class)                        \
struct VTBL_STRU_NAME(class)

/* 类继承自父类的虚函数信息 */
#define INHERITED_V_METHOD(p_class)                         \
struct VTBL_STRU_NAME(p_class) parent_vtbl

/* 单个虚函数声明处 */
#define DEFINE_V_METHOD(ret_type, method)                   \
ret_type (* method )(void* this, ...)

/* 类中的虚函数声明结束宏 */
#define END_V_METHOD_DEFINE(class)

/* 根类的对象声明 */
#define ROOT_CLASS_DECLARE(class)                           \
struct VTBL_STRU_NAME(class) *vbtl;

/* 类中的声明结束宏 */
#define END_CLASS(class)
/* ========================================================================  */

/* 虚拟函数指针的使用 */
#define GET_V_METHOD_PTR(class, func)                                       \
( VTBL_FUNC_PTR_NAME(class, func) )

/* 定义虚拟函数的类型 */
#define DEFINE_V_METHOD_TYPE(ret_type, class, method)                       \
typedef ret_type (* METHOD_TYPE(class, method) )

/* 定义虚拟函数的指针: 修改为奇数场景 */
#define DEFINE_V_METHOD_PTR(class, method)                                  \
enum { VTBL_FUNC_PTR_NAME(class, method) =                              \
((((int )(&((struct VTBL_STRU_NAME(class) *)0)-> method ))          \
/ sizeof(std_func_ptr))<<1) + 1 };                              \

/* 定义继承的虚拟函数的指针 */
#define INHERITED_V_METHOD_PTR(class, parent, method)                       \
enum { VTBL_FUNC_PTR_NAME(class, method) =                              \
VTBL_FUNC_PTR_NAME(parent, method) };                       \

/* 定义普通的虚拟函数的信息 */
#define DEFINE_V_METHOD_INFO(ret_type, class, method)                       \
DEFINE_V_METHOD_PTR(class, method);                                     \
DEFINE_V_METHOD_TYPE(ret_type, class, method)

/* 定义继承的虚拟函数的信息 */
#define INHERITED_V_METHOD_INFO(ret_type, class, parent, method)            \
INHERITED_V_METHOD_PTR(class, parent, method);                          \
DEFINE_V_METHOD_TYPE(ret_type, class, method)

/* 定义普通的成员函数的信息 */
#define DEFINE_C_METHOD_INFO(ret_type, class, method)                       \
extern ret_type METHOD(class, method)
/*
#define DEFINE_C_METHOD_INFO(ret_type, class, method)                       \
extern common_func_ptr __##class##_##method##_ptr__;                    \
typedef ret_type (* VTBL_FUNC_PTR_NAME(class, func) )
*/

/* 调用对象的虚拟函数 */
#define CALL_V_METHOD(object, method_ptr)                                   \
(*(((*( common_func_ptr **) object ))[ ((unsigned int)method_ptr) >> 1 ]))

/* 调用对象的虚拟函数:支持参数严格校验 */
#define CALL_V_R_METHOD(object, class, method)                              \
(*(((*( METHOD_TYPE(class, method) **) object ))[ GET_V_METHOD_PTR(class,method) >> 1 ]))

/* 调用对象的普通成员函数 */
#define CALL_C_METHOD(object, class, method)                                \
METHOD(class, method)
/*
#define DECLARE_V_METHOD(ret_type, class, method)                           \
ret_type METHOD(class, method)

#define DECLARE_C_METHOD(ret_type, class, method)                           \
common_func_ptr __##class##_##method##_ptr__ = METHOD(class, method);   \
ret_type METHOD(class, method)

#define CALL_C_METHOD(ret_type, class, method)                              \
*(VTBL_FUNC_PTR_NAME(class, method)__##class##_##method##_ptr__)
*/

/* ========================================================================  */
/* 实现类,主要是绑定类的虚拟函数指针 */
#define BEGIN_DECLARE_CLASS_VTABLE(class)                                   \
static std_func_ptr VTBL_ENTITY_NAME(class) [                           \
sizeof(struct VTBL_STRU_NAME(class) )/sizeof(std_func_ptr)] = {0};  \
static char VTBL_ENTITY_IS_INIT_FLAG(class) = 0;                        \
static int VTBL_ENTITY_INIT_METHOD(class) (std_func_ptr *vtbl)          \
{                                                                       \
if (0 != VTBL_ENTITY_IS_INIT_FLAG(class) ) return 1;                \
if (0 == vtbl) return 0;                                            \
do

/* 继承父类的VTABLE */
#define INHERITED_VTABLE_INIT(parent)                                       \
if (0 == VTBL_ENTITY_INIT_METHOD_PTR(parent) (vtbl)) return 0

/* 继承的虚函数表项初始化 */
#define INHERITED_VTABLE_METHOD_INIT(class, parent, method)                 \
vtbl[((int )(&((struct VTBL_STRU_NAME(parent) * )0)-> method ))     \
/ sizeof(std_func_ptr)]                                 \
= (std_func_ptr) METHOD(class, method)

/* 自身的虚函数表项初始化 */
#define SELF_VTABLE_METHOD_INIT(class, method)                              \
INHERITED_VTABLE_METHOD_INIT(class, class, method)

/* 实现类的结束宏 */
#define END_DECLARE_CLASS_VTABLE(class)                                     \
while(0);                                                           \
VTBL_ENTITY_IS_INIT_FLAG(class) = 1;                                \
return 1;                                                           \
}                                                                       \
class_vtable_init VTBL_ENTITY_INIT_STRU_VAR(class) =                    \
{ VTBL_ENTITY_INIT_METHOD(class), VTBL_ENTITY_NAME(class)};

/* ========================================================================  */

/* ========================================================================  */
/* 类的构造函数,主要提供两个接口:
一个是create,以支持new,
一个是constructor,就是构造并初始化的函数 */
#define BEGIN_CONSTRUCTOR(class, parent)                                    \
extern int METHOD(class, constructor) (class * this);                   \
class* METHOD(class, create) (void)                                     \
{                                                                       \
return common_create_object(sizeof( class ),                        \
(std_func_ptr) METHOD(class, constructor));                     \
}                                                                       \
\
int METHOD(class, constructor) (class * this)                           \
{                                                                       \
VTBL_ENTITY_INIT_METHOD(class) ( VTBL_ENTITY_NAME(class) );         \
if (0 != METHOD(parent, constructor) (( parent *)(this)))           \
return 1;                                                       \
*(struct  VTBL_STRU_NAME(class) **)this =                           \
(struct VTBL_STRU_NAME(class) *) VTBL_ENTITY_NAME(class) ;      \
do                                                                  \

/* 类构造函数的结束宏 */
#define END_CONSTRUCTOR(class, parent)                                      \
while(0);                                                           \
return 0;                                                           \
}
/* 根类的父类构造函数为0 */
#define void_constructor(this)          (0)
/* ========================================================================  */

/* ========================================================================  */
/* 类的析构函数,主要提供两个接口:
一个是destory,以支持delete,
一个是destructor,就是析构函数 */
#define BEGIN_DESTRUCTOR(class, parent)                                     \
extern int METHOD(class, destructor) (class * this);                    \
void METHOD(class, destory) ( class * this)                             \
{                                                                       \
common_destory_object( this ,                                       \
(std_func_ptr) METHOD(class, destructor) );                     \
}                                                                       \
\
int METHOD(class, destructor) (class * this)                            \
{                                                                       \
do                                                                  \

/* 类析构函数的结束宏 */
#define END_DESTRUCTOR(class, parent)                                       \
while(0);                                                           \
if (0 != METHOD(parent, destructor) (( parent *)(this)))            \
return 1;                                                       \
return 0;                                                           \
}
/* 根类的父类析构函数为0 */
#define void_destructor(this)          (0)

/* ========================================================================  */

typedef int (*std_func_ptr)(void*);
typedef int (*common_func_ptr)(void*, ...);

typedef struct
{
int (*vtable_init_method)(std_func_ptr*);
std_func_ptr vtable_array;
}class_vtable_init;

void* common_create_object(unsigned int size, std_func_ptr pCtor);
void  common_destory_object(void* this, std_func_ptr pDtor);
void  common_destory_object_non_virtual(void* this, std_func_ptr pDtor);

#ifdef __cplusplus
};
#endif /* end of __cplusplus */

#endif


#include "ooc.hoo"
#include <stdio.h>
#include <stdlib.h>

void* common_create_object(unsigned int size, std_func_ptr pCtor)
{
/* 分配对象 */
void* object = malloc(size);
/* 如果分配失败,返回0 */
if (0 == object)
return 0;
/* 调用构造函数 */
if (0 != (*pCtor)(object))
{
/* 构造函数执行失败,释放对象 */
free(object);
return 0;
}
/* 成功,返回对象 */
return object;
}

void  common_destory_object(void* this, std_func_ptr pDtor)
{
/* 如果对象为空 */
if (0 == this)  return;
/* 如果存在虚函数表指针 */
if (0 != *(void**)this)
{
/* 调用虚函数表中的第一个函数指针,默认此函数为析构函数 */
if (0 != (*((*(std_func_ptr**)this)[0]))((void*)this))
return;
}
else
{
/* 不为空,则调用传入的析构函数指针 */
if (0 != (*pDtor)(this))
return;
}
/* 最后释放对象 */
free(this);
}

void  common_destory_object_non_virtual(void* this, std_func_ptr pDtor)
{
if (0 == this)  return;
if (0 != (*pDtor)(this))
return;
/* free */
free(this);
}


#ifndef __BASE_OBJECT_STRUCT__
#define __BASE_OBJECT_STRUCT__

#include <glib.h>
#include <glib-object.h>
#include "ooc.hoo"

#ifdef __cplusplus
extern "C" {
#endif

#ifndef __GNUC__
#define SIGNAL_CALLBACK __cdcel
#else
#define SIGNAL_CALLBACK __attribute__((cdecl))
#endif

BEGIN_CLASS(BaseObject)
{
/* 类自身的数据 */
ROOT_CLASS_DECLARE(BaseObject)
/* 虚拟函数表的定义处 */
BEGIN_V_METHOD_DEFINE(BaseObject)
{
/* 自身的虚函数 */
DEFINE_V_METHOD(int, destructor);
/* 自身的虚函数 */
DEFINE_V_METHOD(gulong, setupObject);
}
END_V_METHOD_DEFINE(BaseObject);

/* 对象的数据 */
GObject*    x_pObject;
GSList*     x_pObjectList;
}
END_CLASS(BaseObject);

typedef gulong (*CommonCallback)(BaseObject* this, GObject*instance, ...);

typedef struct ObjectCallbackInfo
{
BaseObject*     x_pThis;
CommonCallback  x_pCallback;
GObject*        x_pWidget;
} ObjectCallbackInfo;

DEFINE_V_METHOD_INFO(int    , BaseObject, destructor) (BaseObject* this);
DEFINE_V_METHOD_INFO(gulong , BaseObject, setupObject) (BaseObject* this);
DEFINE_C_METHOD_INFO(gulong , BaseObject, ConnectSignal) (BaseObject* this, gpointer instance, const gchar *detailed_signal, CommonCallback c_handler);
DEFINE_C_METHOD_INFO(gulong , BaseObject, SignalProc) (const ObjectCallbackInfo* lpObject, ...);

#ifdef __cplusplus
};
#endif /* end of __cplusplus */

#endif


#include "BaseObject.hoo"

gulong METHOD(BaseObject, SignalProc)(const ObjectCallbackInfo* lpObject, ...)
{
va_list pArgList;
gulong ulRetcode;
struct reserve_arg { gulong ulReserver[20];} *pstTemp;

/* 收到信号时,先判断指针 */
if ( (NULL == lpObject) || (NULL == lpObject->x_pCallback ) || (NULL == lpObject->x_pWidget))
{
return 0;
}
/* 取出this指针及成员函数指针 */
va_start(pArgList, lpObject);
pstTemp = (struct reserve_arg*)pArgList;

/* 调用成员函数 */
if ((((unsigned int)lpObject->x_pCallback) & 0x1) == 0x1)
{
printf("enter virtual method branch!\n");
ulRetcode = CALL_V_METHOD ((lpObject->x_pThis), (lpObject->x_pCallback)) (lpObject->x_pThis, lpObject->x_pWidget, *pstTemp);
}
else
{
ulRetcode = (*(lpObject->x_pCallback))(lpObject->x_pThis, lpObject->x_pWidget, *pstTemp);
}

va_end(pArgList);

return ulRetcode;
}

gulong METHOD(BaseObject, ConnectSignal)(BaseObject* this, gpointer instance,
const gchar *detailed_signal,
CommonCallback c_handler)
{
/* 分配存放回调指针的空间 */
ObjectCallbackInfo* lpObject = (ObjectCallbackInfo*)g_malloc(sizeof(ObjectCallbackInfo));
if (NULL == lpObject)
{
return 0;
}
lpObject->x_pThis     = this;
lpObject->x_pCallback = c_handler;
lpObject->x_pWidget   = (GObject*)instance;
/* 将信息保存在slist中 */
this->x_pObjectList = g_slist_append(this->x_pObjectList, lpObject);

/* 注册信号回调 */
return g_signal_connect_swapped(instance, detailed_signal,
(GCallback)&( METHOD(BaseObject, SignalProc) ),
(gpointer)lpObject);
}

BEGIN_DECLARE_CLASS_VTABLE(BaseObject)
{
SELF_VTABLE_METHOD_INIT(BaseObject, destructor);
}
END_DECLARE_CLASS_VTABLE(BaseObject)

BEGIN_CONSTRUCTOR(BaseObject, void)
{
this->x_pObject = NULL;
this->x_pObjectList = NULL;
}
END_CONSTRUCTOR(BaseObject, void)

BEGIN_DESTRUCTOR(BaseObject, void)
{
/* 释放所有分配的ObjectToMemFunc空间 */
gpointer lpObj;
GSList* lpTempList = this->x_pObjectList;
while (NULL != lpTempList)
{
/* 如果非空 */
lpObj = g_slist_nth_data(lpTempList, 0);
if (NULL != lpObj)
{
g_free(lpObj);
}

lpTempList = g_slist_next(lpTempList);
}
/* 删除列表 */
if (NULL != this->x_pObjectList)
{
g_slist_free(this->x_pObjectList);
}
}
END_DESTRUCTOR(BaseObject, void)


#ifndef __UI_TEST_WIN__
#define __UI_TEST_WIN__

#include "BaseObject.hoo"
#include <gtk/gtk.h>

/* 测试的第一个类 */
BEGIN_CLASS(TestDialog)
{
/* 继承自NullClass */
INHERITED_PARENT(BaseObject);

/* 虚拟函数表的定义处 */
BEGIN_V_METHOD_DEFINE(TestDialog)
{
/* 继承自NullClass */
INHERITED_V_METHOD(BaseObject);
/* 自身的虚函数 */
DEFINE_V_METHOD(SIGNAL_CALLBACK gulong, OnOk) ;
DEFINE_V_METHOD(SIGNAL_CALLBACK gulong, OnChange) ;
}
END_V_METHOD_DEFINE(TestDialog);

/* 类自身的数据 */
/* GtkWidget *calendar1; */
GtkWidget *notebook1;
GtkWidget *empty_notebook_page;
GtkWidget *label1;
GtkWidget *label2;
GtkWidget *label3;
}
END_CLASS(TestDialog);

INHERITED_V_METHOD_INFO(int , TestDialog, BaseObject, destructor) (TestDialog* this);
INHERITED_V_METHOD_INFO(int,  TestDialog, BaseObject, setupObject) (TestDialog* this);
DEFINE_V_METHOD_INFO(SIGNAL_CALLBACK gulong, TestDialog, OnOk) (TestDialog* this, GtkWidget *notebook1);
DEFINE_V_METHOD_INFO(SIGNAL_CALLBACK gulong, TestDialog, OnChange) (TestDialog* this, GtkWidget *notebook1, GtkNotebookPage *page, guint num);

#endif


#include "ui_testwin.hoo"

gulong METHOD(TestDialog, OnOk)(TestDialog* this, GtkWidget *notebook1)
{
printf("this        : %08x\n", this);
printf("notebook    : %08x\n", notebook1);
fflush(stdout);
gtk_main_quit();
return 0;
}

gulong METHOD(TestDialog, OnChange)(TestDialog* this, GtkWidget *notebook1, GtkNotebookPage *page, guint num)
{
printf("this        : %08x\n", this);
printf("notebook    : %08x\n", notebook1);
printf("page        : %08x\n", page);
printf("Current Page: %d(%08x)\n", num, num);
return 0;
}

gulong METHOD(TestDialog, setupObject)(TestDialog* this)
{
GtkWidget* window1 = gtk_window_new (GTK_WINDOW_TOPLEVEL);
gtk_window_set_title (GTK_WINDOW (window1), "window1");

METHOD(BaseObject, ConnectSignal) (this, G_OBJECT (window1), "destroy", (CommonCallback)( GET_V_METHOD_PTR(TestDialog, OnOk )));

this->notebook1 = gtk_notebook_new ();
gtk_widget_show (this->notebook1);
gtk_container_add (GTK_CONTAINER (window1), this->notebook1);

this->empty_notebook_page = gtk_vbox_new (FALSE, 0);
gtk_widget_show (this->empty_notebook_page);
gtk_container_add (GTK_CONTAINER (this->notebook1), this->empty_notebook_page);

this->label1 = gtk_label_new (("label1"));
gtk_widget_show (this->label1);
gtk_notebook_set_tab_label (GTK_NOTEBOOK (this->notebook1), gtk_notebook_get_nth_page (GTK_NOTEBOOK (this->notebook1), 0), this->label1);

this->empty_notebook_page = gtk_vbox_new (FALSE, 0);
gtk_widget_show (this->empty_notebook_page);
gtk_container_add (GTK_CONTAINER (this->notebook1), this->empty_notebook_page);

this->label2 = gtk_label_new (("label2"));
gtk_widget_show (this->label2);
gtk_notebook_set_tab_label (GTK_NOTEBOOK (this->notebook1), gtk_notebook_get_nth_page (GTK_NOTEBOOK (this->notebook1), 1), this->label2);

this->empty_notebook_page = gtk_vbox_new (FALSE, 0);
gtk_widget_show (this->empty_notebook_page);
gtk_container_add (GTK_CONTAINER (this->notebook1), this->empty_notebook_page);

this->label3 = gtk_label_new (("label3"));
gtk_widget_show (this->label3);
gtk_notebook_set_tab_label (GTK_NOTEBOOK (this->notebook1), gtk_notebook_get_nth_page (GTK_NOTEBOOK (this->notebook1), 2), this->label3);

METHOD(BaseObject, ConnectSignal) (this,  G_OBJECT (this->notebook1), "switch-page", (CommonCallback)(GET_V_METHOD_PTR(TestDialog,OnChange)));

/* Store pointers to all widgets, for use by lookup_widget(). */
//GLADE_HOOKUP_OBJECT_NO_REF (window1, window1, "window1");
//GLADE_HOOKUP_OBJECT (window1, calendar1, "calendar1");
gtk_widget_show(window1);

/* 存放对象的基类指针 */
this->parent.x_pObject = (GObject*)window1;

return 0;
}

BEGIN_DECLARE_CLASS_VTABLE(TestDialog)
{
INHERITED_VTABLE_INIT(BaseObject);

INHERITED_VTABLE_METHOD_INIT(TestDialog, BaseObject, destructor);
INHERITED_VTABLE_METHOD_INIT(TestDialog, BaseObject, setupObject);

SELF_VTABLE_METHOD_INIT(TestDialog, OnOk);
SELF_VTABLE_METHOD_INIT(TestDialog, OnChange);
}
END_DECLARE_CLASS_VTABLE(TestDialog)

BEGIN_CONSTRUCTOR(TestDialog, BaseObject)
{
}
END_CONSTRUCTOR(TestDialog, BaseObject)

BEGIN_DESTRUCTOR(TestDialog, BaseObject)
{
}
END_DESTRUCTOR(TestClass, BaseObject)

int main (int argc, char *argv[])
{
TestDialog* lpDialog = NULL;

gtk_init(&argc, &argv);

lpDialog = new(TestDialog);

CALL_V_R_METHOD(lpDialog, TestDialog, setupObject)(lpDialog);

gtk_main ();

delete(TestDialog, lpDialog);

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: