• 如何将GTK+2.0的信号、回调处理映射成类成员函数的调用VC中测试(虚拟继承类及多继承)


    // TestDelegate.cpp : 定义控制台应用程序的入口点。
    //

    #include "stdafx.h"

    typedef unsigned long gulong;
    typedef char gchar;
    typedef void* gpointer;
    typedef long GObject;

    void* g_lpObject = 0;


    class Object
    {
    public:
        Object() {};
        virtual ~Object() {};
    };

    class BaseObject: virtual public Object
    {
    public:
        BaseObject();
        virtual ~BaseObject();

        /* 创建对象并绑定信号的接口 */
        virtual gulong setupObject() = 0;

    //protected:
        typedef gulong (BaseObject::* CommonCallback)(GObject*instance, ...);

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

        GObject*    x_pObject;

        gulong ConnectSignal(gpointer instance, const gchar *detailed_signal, CommonCallback c_handler);

    //private:
        
    //GSList* x_pObjectList;

        static gulong SignalProc(const ObjectCallbackInfo* lpObject, ...);
    };

    #include <stdarg.h>
    #include <stdio.h>
    #include <stdlib.h>

    BaseObject::BaseObject():x_pObject(NULL)
    {
    }

    BaseObject::~BaseObject()
    {
        /* 释放所有分配的ObjectToMemFunc空间 */
    }

    gulong BaseObject::ConnectSignal(gpointer instance, 
                                     const gchar *detailed_signal,
                                     CommonCallback c_handler)
    {
        /* 分配存放回调指针的空间 */
        ObjectCallbackInfo* lpObject = (ObjectCallbackInfo*)malloc(sizeof(ObjectCallbackInfo));
        if (NULL == lpObject)
        {
            return 0;
        }
        lpObject->x_pThis     = this;
        lpObject->x_pCallback = c_handler;
        lpObject->x_pWidget   = (GObject*)instance;

        printf("Object  :  0x%08x\n", lpObject);
        printf("This    :  0x%08x\n", lpObject->x_pThis);
        printf("Callback:  0x%08x\n", lpObject->x_pCallback);
        printf("Widget  :  0x%08x\n", lpObject->x_pWidget);

        /* 将信息保存在slist中 */
        //x_pObjectList = g_slist_append(x_pObjectList, lpObject);

        /* 注册信号回调 */
        /* return g_signal_connect_swapped(instance, detailed_signal, 
                                       &(BaseObject::SignalProc), lpObject);
    */
        g_lpObject = lpObject;
    }

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

        /* 收到信号时,先判断指针 */
        if ( (NULL == lpObject) )//|| (NULL == lpObject->x_pCallback ) || (NULL == lpObject->x_pWidget))
        {
            return 0;
        }

        printf("Object  :  0x%08x\n", lpObject);
        printf("This    :  0x%08x\n", lpObject->x_pThis);
        printf("Callback:  0x%08x\n", lpObject->x_pCallback);
        printf("Widget  :  0x%08x\n", lpObject->x_pWidget);

        /* 取出this指针及成员函数指针 */
        va_start(pArgList, lpObject);
        pstTemp = (struct reserve_arg*)pArgList;
        lpThis = lpObject->x_pThis;
        pCallBack = lpObject->x_pCallback;
        printf("Param   :  %08x %08x %08x %08x\n", pstTemp->ulReserver[0], pstTemp->ulReserver[1], pstTemp->ulReserver[2], pstTemp->ulReserver[3]);
        
        /* 调用成员函数 */
        ulRetcode = (lpThis ->* pCallBack)(lpObject->x_pWidget, *pstTemp);
        
        va_end(pArgList);

        printf("Object  :  0x%08x\n", lpObject);
        printf("This    :  0x%08x\n", lpObject->x_pThis);
        printf("Callback:  0x%08x\n", lpObject->x_pCallback);
        printf("Widget  :  0x%08x\n", lpObject->x_pWidget);

        return ulRetcode;
    }

    class TestDialog1: public BaseObject
    {
    public:
        //virtual gulong setupObject();

    protected:  
        virtual gulong __cdecl OnChange1(void *notebook1, void *page, unsigned int num);
    };

    class TestDialog2: public BaseObject
    {
    public:
        //virtual gulong setupObject();
        
    protected:  
        virtual gulong __cdecl OnChange2(void *notebook1, void *page, unsigned int num);
    };


    class TestDialog: public TestDialog1, public TestDialog2
    {
    public:
        virtual gulong setupObject();
        
    protected:  
        //virtual gulong __cdecl OnChange1(void *notebook1, void *page, unsigned int num);
    };

    //函数指针转换,可以把一种类型的数据直接转换成第二种类型的数据
    template <class FuncPt1, class FuncPt2>
    inline FuncPt1 Func_Cast(FuncPt2 pt1)
    {
        union __TranPt1ToPt2
        {
            FuncPt2 pointer2;
            FuncPt1 pointer1;
            unsigned long data[5];
            unsigned long* pt;
        } __Tran = {pt1};
        printf("size of FuncPt1: %u\n"sizeof(FuncPt1));
        printf("size of FuncPt2: %u\n"sizeof(FuncPt2));
        printf("real value     : %08x, %08x, %08x, %08x\n", __Tran.data[0], __Tran.data[1], __Tran.data[2], __Tran.data[3]);
        //printf("pt   value     : %08x\n", *(__Tran.pt));
        return __Tran.pointer1;
    }

    gulong TestDialog::setupObject()
    {
        TestDialog2::ConnectSignal((void*)123"destroy", Func_Cast<CommonCallback>(&TestDialog2::OnChange2));
        
        return 0;
    }

    gulong TestDialog1::OnChange1(void *notebook1, void *page, unsigned int num)
    {
        printf("TestDialog1::OnChange1\n");
        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 TestDialog2::OnChange2(void *notebook1, void *page, unsigned int num)
    {
        printf("TestDialog2::OnChange2\n");
        printf("this        : %08x\n"this);
        printf("Current Page: %d(%08x)\n", num, num);
        return 0;
    }

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

        lpDialog = new TestDialog;
        lpDialog->setupObject();
        BaseObject::SignalProc((const BaseObject::ObjectCallbackInfo *)g_lpObject, 2344563);

        delete lpDialog;
        getchar();

        return 0;
    }

    注:在GCC中也调试通过(mingw32)

  • 相关阅读:
    ASP.NET 2.0 用户注册控件的密码验证问题
    编程使用GridView,DataList的模版列
    在您的站点上添加 Windows Live Favourites 收藏入口
    推荐个很好玩的开源项目Ascii Generator dotNET
    Castle ActiveRecord 在Web项目和WinForm项目中
    HTML解析器项目进展和新的构思
    SilverLight 的跨域跨域访问
    SQL 语句之Join复习
    【笔记】提高中文分词准确性和效率的方法
    ASP.NET 动态加载控件激发事件的问题
  • 原文地址:https://www.cnblogs.com/eaglexmw/p/3058434.html
Copyright © 2020-2023  润新知