Imitate virtual table using struct

Common.h

//

//===================================================================

//

#pragmawarning( disable : 4311 4312 4313 )

 

//

//===================================================================

//

#define           mem_addr                                 DWORD

#define           vfptr                                    mem_addr*

#define           fptr                                     mem_addr*

 

//

//===================================================================

//

#define           SAFE_DELETE(x)                           { if (x) delete (x); (x) = NULL; }

#define           SAFE_DELETEARRAY(x)                      { if (x) delete[] (x); (x) = NULL; }

 

//

//===================================================================

//

#define           GET_ELEMENT_ADDRESS( obj, ofs )          (((LPBYTE)&(obj))+(ofs))

#define           GET_ELEMENT_PTR( type, obj, ofs )        (type*)GET_ELEMENT_ADDRESS( obj, ofs )

#define           GET_ELEMENT_VALUE( type, obj, ofs )      *GET_ELEMENT_PTR( type, obj, ofs )

 

#define           GET_VFPTR( obj, ofs )                    (vfptr)GET_ELEMENT_VALUE( mem_addr, obj, ofs )

#define           GET_FPTR( _vfptr, idx )                  (fptr)(*((fptr)(_vfptr) + idx))

  

//

//===================================================================

//

typedef           void (*PFUN) ( void );

 

//

//===================================================================

//

 Class.h

//

//===================================================================

//

 

class_A

{

public:

    _A() : nInt(0){

    };

 

public:

    void virtual Fun1( void )

    {

        printf( "/t/t _A::Fun1(void) /t/r/n" );

    }

 

    void virtual Fun2( void )

    {

        printf( "/t/t _A::Fun2(void) /t/r/n" );

    }

 

    int     nInt;

};

 

class_B

{

public:

    void virtual Fun3( void )

    {

        printf( "/t/t _B::Fun3(void) /t/r/n" );

    }

 

    void virtual Fun4( void )

    {

        printf( "/t/t _B::Fun4(void) /t/r/n" );

    }

 

};

 

class_C : public _A, _B

{

public:

    void virtual Fun1( void )

    {

        printf( "/t/t _C::Fun1(void) /t/r/n" );

    }

 

    void virtual Fun2( void )

    {

        printf( "/t/t _C::Fun2(void) /t/r/n" );

    }

 

    void virtual Fun3( void )

    {

        printf( "/t/t _C::Fun3(void) /t/r/n" );

    }

 

    void virtual Fun4( void )

    {

        printf( "/t/t _C::Fun4(void) /t/r/n" );

    }

};

//

//===================================================================

//

Struct.h

//

//===================================================================

//

 

voidA_Fun1(void);

voidA_Fun2(void);

voidB_Fun3(void);

voidB_Fun4(void);

 

voidC_Fun1(void);

voidC_Fun2(void);

voidC_Fun3(void);

voidC_Fun4(void);

 

externDWORD dwRewriteState;

//

//===================================================================

//

#define REWRITE_FUN1 0x0001

#define REWRITE_FUN2 0x0002

#define REWRITE_FUN3 0x0004

#define REWRITE_FUN4 0x0008  

//

//===================================================================

//

 

typedefstructtagVirtualTableA

{

    fptrFun1;

    fptrFun2;

 

    tagVirtualTableA() : Fun1(NULL), Fun2(NULL)

    {

        InitInstance( A_Fun1, A_Fun2 );

    };

 

    voidInitInstance( PFUN fun1, PFUN fun2 )

    {

        Fun1 = (fptr)fun1;

        Fun2 = (fptr)fun2;

    }

 

}VirtualTableA, *LPVirtualTableA;

 

typedefstructtagVirtualTableB

{

    fptrFun3;

    fptrFun4;

 

    tagVirtualTableB() : Fun3(NULL), Fun4(NULL)

    {

        InitInstance( B_Fun3, B_Fun4 );

    };

 

    voidInitInstance( PFUN fun3, PFUN fun4 )

    {

        Fun3 = (fptr)fun3;

        Fun4 = (fptr)fun4;

    }

 

}VirtualTableB, *LPVirtualTableB;

 

externLPVirtualTableA lpvfA;

struct A

{

    LPVirtualTableA   __vfptr;

    int               nInt;

 

    A() : __vfptr(NULL), nInt(0)

    {

        __vfptr = lpvfA;

    }

 

    ~A()

    {

        __vfptr = NULL;

    }

};

 

externLPVirtualTableB lpvfB;

struct B

{

    LPVirtualTableB   __vfptr;

 

    B() : __vfptr(NULL)

    {

        __vfptr = lpvfB;

    }

 

    ~B()

    {

        __vfptr = NULL;

    }

};

 

structC :publicA,publicB

{

    C() : A(), B()

    {

    }

};

 

voidInitVirtualTable(void);

voidExitVirtualTable(void);

 

//

//===================================================================

//

 

voidTestEx(void);

 

//

//===================================================================

//

 

Class.cpp

//

//===================================================================

//

voidA_Fun1(void)

{

    printf( "/t/t A::Fun1(void) /t/r/n" );

};

 

voidA_Fun2(void)

{

    printf( "/t/t A::Fun2(void) /t/r/n" );

};

 

voidB_Fun3(void)

{

    printf( "/t/t B::Fun3(void) /t/r/n" );

};

 

voidB_Fun4(void)

{

    printf( "/t/t B::Fun4(void) /t/r/n" );

};

 

voidC_Fun1(void)

{

    printf( "/t/t C::Fun1(void) /t/r/n" );

};

 

voidC_Fun2(void)

{

    printf( "/t/t C::Fun2(void) /t/r/n" );

};

 

voidC_Fun3(void)

{

    printf( "/t/t C::Fun3(void) /t/r/n" );

};

 

voidC_Fun4(void)

{

    printf( "/t/t C::Fun4(void) /t/r/n" );

};

 

DWORDdwRewriteState = REWRITE_FUN1 | REWRITE_FUN2 | REWRITE_FUN3 | REWRITE_FUN4;

 

BOOLIsRewriteFun1(void){return(dwRewriteState & REWRITE_FUN1); }

BOOLIsRewriteFun2(void){return(dwRewriteState & REWRITE_FUN2); }

BOOLIsRewriteFun3(void){return(dwRewriteState & REWRITE_FUN3); }

BOOLIsRewriteFun4(void){return(dwRewriteState & REWRITE_FUN4); }

//

//===================================================================

//

 

LPVirtualTableAlpvfA = NULL;

LPVirtualTableBlpvfB = NULL;

 

voidInitVirtualTable(void)

{

    ExitVirtualTable();

 

    lpvfA =newVirtualTableA;

    lpvfB =newVirtualTableB;

 

    PFUN fun1(NULL), fun2(NULL), fun3(NULL), fun4(NULL);

 

    fun1 = IsRewriteFun1() ? C_Fun1 : A_Fun1;

    fun2 = IsRewriteFun2() ? C_Fun2 : A_Fun2;

    fun3 = IsRewriteFun3() ? C_Fun3 : B_Fun3;

    fun4 = IsRewriteFun4() ? C_Fun4 : B_Fun4;

 

    lpvfA->InitInstance( fun1, fun2 );

    lpvfB->InitInstance( fun3, fun4 );

}

 

voidExitVirtualTable(void)

{

    SAFE_DELETE(lpvfA);

    SAFE_DELETE(lpvfB);

}

 

//

//===================================================================

//

 

voidTestEx(void)

{

    InitVirtualTable();

 

    C cObj;

    PRINT_OBJECT_NAME( "[Instance of struct C] : cObj" );

    PRINT_OBJECT_ADDRESS( cObj );

    PRINT_OBJECT_SIZE( cObj );

 

    PFUN Fun = NULL;

 

    vfptr _vfptrA = GET_VFPTR( cObj, 0 );

    PRINT_VFPTR_VALUE( _vfptrA );

 

    Fun = (PFUN)GET_FPTR( _vfptrA, 0 );

    Fun();

    PRINT_FPTR_VALUE( Fun );

    PRINT_FPTR_ADDRESS( _vfptrA + 0 );

 

    Fun = (PFUN)GET_FPTR( _vfptrA, 1 );

    Fun();

    PRINT_FPTR_VALUE( Fun );

    PRINT_FPTR_ADDRESS( _vfptrA + 1 );

 

    vfptr _vfptrB = GET_VFPTR( cObj,sizeof(vfptr)+sizeof(int) );

    PRINT_VFPTR_VALUE( _vfptrB );

 

    Fun = (PFUN)GET_FPTR( _vfptrB, 0 );

    Fun();

    PRINT_FPTR_VALUE( Fun );

    PRINT_FPTR_ADDRESS( _vfptrB + 0 );

 

    Fun = (PFUN)GET_FPTR( _vfptrB, 1 );

    Fun();

    PRINT_FPTR_VALUE( Fun );

    PRINT_FPTR_ADDRESS( _vfptrB + 1 );

 

    PRINT_NEWLINE();

 

    ExitVirtualTable();

}

_C _cObj;// Class _C;

C cObj;// Struct C


版权声明:本文为MLiang原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。