#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; }