如何将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)

原文地址:https://www.cnblogs.com/eaglexmw/p/3058434.html