Call the address of the class member function directly (address of class member function with assembler, different vs version)

Source: Internet
Author: User

In C + +, a pointer to a member function is a very special thing. For a normal function pointer, it can be treated as an address and can be arbitrarily converted and called directly when needed. However, for member functions, general type conversions are not compiled and must be called with special syntax. C + + specifically prepares three operators for member pointers: "::*" for the declaration of pointers, while "->*" and ". *" are used to invoke the function pointed to by the pointer.

//Thunk.cpp:Defines the entry point for the console application.//#include"stdafx.h"typedef unsignedintDWORD;//takes the address of the class member function. VC8 version. The private member function address can be taken .#defineGetmemberfuncaddr_vc8 (Funcaddr,functype) \{__asm {                                                mov eax,offset functype}; __asm {mov Fu                                            Ncaddr, eax}; }//takes the address of the class member function. VC6 version.Template <classToType,classFromtype>voidGETMEMBERFUNCADDR_VC6 (totype&Addr,fromtype F)        {union {Fromtype _f;    ToType _t;    }ut; Ut._f=F; Addr=ut._t;}//calling class member functionsDWORD Callmemberfunc (intCallflag,dword Funcaddr,void*this,intCount,...)    {DWORD re; if(count>0)//Parameters are pressed into the stack.{__asm {mov ecx,count;//number of parameters, ECX, loop counter.mov edx,ecx; SHL edx,2; Add edx,0x14; edx = count*4+0x14; Next:push DWORD Ptr[ebp+edx]; Sub edx,0x4;        Dec ecx jnz Next; }    }    //processes the this pointer.    if(callflag==0)//__THISCALL,VC The default member function invocation type.{__asm mov ecx,this; }    Else//__stdcall{__asm push this; } __asm//calling Functions{call funcaddr;//Call 1. Press the address of the next line of the program into the stack; 2. JMP to the address of the subroutine at call. mov re,eax; }    returnre;}//////////////////////////////////////////////////////////////////////////////////////////////////voidTest1 ()//demonstrates the use of C + + member function pointers.{   classTT { Public:voidFoointx) {printf ("\ n%d \ n", x);   }   }; typedefvoid(TT::* functype) (int); Functype ptr= &tt::foo;//assigns a value to a member function pointer.TT A; (A.*PTR) (5);//invokes a member function pointer.TT*b =Newtt; (b-&GT;*PTR) (6);//invokes a member function pointer.    Deleteb;//DWORD dwfooaddrptr= 0;//dwfooaddrptr = (DWORD) &tt::foo; /* Error C2440 * ///dwfooaddrptr = reinterpret_cast<dword> (&tt::foo);/* Error C2440 */}voidTest2 ()//demonstrates how to take a member function address.{   classTT { Public:voidFoointx) {printf ("\ n%d \ n", x); }   };#if_msc_ver >1200DWORD dwAddrPtr1;    Getmemberfuncaddr_vc8 (Dwaddrptr1,tt::foo); printf ("\ test2 Tt::foo%08x", DWADDRPTR1);#endifDWORD dwAddrPtr2; GETMEMBERFUNCADDR_VC6 (DWADDRPTR2,&Tt::foo); printf ("\ test2 Tt::foo%08x", DWADDRPTR2);}voidTest3 ()//demonstrates how to call a member function address.{    classTT { Public:        voidFoointXCharCChar*s)//no type specified, default is __thiscall.{printf ("\ m_a=%d,%d,%c,%s\n.", m_a,x,c,s); }        void__stdcall Foo2 (intXCharCChar*s)//the member function specifies the __stdcall calling convention.{printf ("\ m_a=%d,%d,%c,%s\n.", m_a,x,c,s); }        intM_a;    }; typedefvoid(__stdcall *functype) (int,Char,Char*);//define the corresponding non-member function pointer type, and note specify __stdcall.typedefvoid(__stdcall *functype2) (void*,int,Char,Char*);//notice One more void * parameter.TT ABC; Abc.m_a=123;    DWORD ptr; DWORD This= (DWORD) &ABC; GETMEMBERFUNCADDR_VC6 (PTR,&tt::foo);//take the member function address.Functype fnfooptr= (Functype) ptr;//Converts a function address into a pointer to a normal function.__asm//prepares the this pointer.{mov ecx, this; } fnfooptr (5,'a',"7xyz");//call the address of a member function like a normal function.getmemberfuncaddr_vc6 (PTR,&AMP;TT::FOO2);//take the member function address.FUNCTYPE2 fnFooPtr2= (FUNCTYPE2) ptr;//Converts a function address into a pointer to a normal function.FNFOOPTR2 (&AMP;ABC,5,'a',"7xyz");//call the address of the member function like a normal function, noting that the first parameter is the this pointer.}voidTest4 ()//demonstrates calling member functions through Callmemberfunc{    classTT { Public:        voidFoointXCharCChar*s)//no type specified, default is __thiscall.{printf ("\ m_a=%d,%d,%c,%s\n.", m_a,x,c,s); }        void__stdcall Foo2 (intXCharCChar*s)//the member function specifies the __stdcall calling convention.{printf ("\ m_a=%d,%d,%c,%s\n.", m_a,x,c,s); }        intM_a;    };    TT ABC; Abc.m_a=123;    DWORD ptr1,ptr2; GETMEMBERFUNCADDR_VC6 (PTR1,&tt::foo);//take the member function address.GETMEMBERFUNCADDR_VC6 (PTR2,&AMP;TT::FOO2);//take the member function address.Callmemberfunc (0, PTR1,&AMP;ABC,3,5,'a',"7xyz");//the first parameter, 0, represents a __thiscall call.Callmemberfunc (1, PTR2,&AMP;ABC,3,5,'a',"7xyz");//the first parameter, 1, represents a non-__thiscall call. }voidTEST5 ()//The demonstration uses the function address in the case of inheritance.{    classTT1 { Public:                voidFoo1 () {printf ("\ Hi, I am in tt1::foo1\n"); }        Virtual voidFoo3 () {printf ("\ Hi, I am in tt1::foo3\n");    }    }; classTT2: PublicTT1 { Public:                voidFoo2 () {printf ("\ Hi, I am in tt2::foo2\n"); }        Virtual voidFoo3 () {printf ("\ Hi, I am in tt2::foo3\n");    }    };    DWORD Tt1_foo3,tt2_foo1,tt2_foo2,tt2_foo3; GETMEMBERFUNCADDR_VC6 (Tt1_foo3,&Tt1::foo3); GETMEMBERFUNCADDR_VC6 (Tt2_foo1,&tt2::foo1); GETMEMBERFUNCADDR_VC6 (Tt2_foo2,&Tt2::foo2); GETMEMBERFUNCADDR_VC6 (Tt2_foo3,&Tt2::foo3);    TT1 x;    Tt2 y; Callmemberfunc (0, Tt1_foo3,&x,0);//Tt1::foo3Callmemberfunc (0, Tt2_foo1,&x,0);//tt2::foo1 = Tt1::foo1Callmemberfunc (0, Tt2_foo2,&x,0);//Tt2::foo2Callmemberfunc (0, Tt2_foo3,&x,0);//Tt2::foo3Callmemberfunc (0, Tt1_foo3,&y,0);//Tt1::foo3Callmemberfunc (0, Tt2_foo1,&y,0);//tt2::foo1 = Tt1::foo1Callmemberfunc (0, Tt2_foo2,&y,0);//Tt2::foo2Callmemberfunc (0, Tt2_foo3,&y,0);//Tt2::foo3}intMainintargcChar*argv[])    {test1 ();    Test2 ();    Test3 ();    Test4 ();   Test5 (); return 0;}

http://download.csdn.net/download/tikycc2/1580557

Call the address of the class member function directly (address of class member function with assembler, different vs version)

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.