函数编译与执行及虚函数剖析(源码论证)

#pragma once/* 类 函数声明*/class Base;class Base1;class Base2;class TestClass;/* PFThisCall1 参数个数固定,,则类stdcall方式编译 但是this指针则由ECX存放 (int parm1)*/typedef void (__stdcall *PFThisCall1)(int parm1);/* PFThisCall2 参数个数不固定,则类cdecl方式编译 this指针会作为形参传递 (TestClassFirst* pThis,int parmCount,int parm1,…) */typedef void (__cdecl *PFThisCall2)(TestClass* pThis,int parmCount,int parm1,…);/* PFunc1代表一个参数的函数(TestClassFirst* pThis)*/typedef void (__stdcall *PFunc1)(TestClass* pThis);/* PFunc2代表两个参数的函数(TestClassFirst* pThis,int parm1)*/typedef void (__stdcall *PFunc2)(TestClass* pThis,int parm1);/* PFunc3代表三个参数的函数(TestClassFirst* pThis,int parm1,int parm2)*/typedef int (__stdcall *PFunc3)(TestClass* pThis,int parm1,int parm2);//类函数指针 原本就是__stdcall函数typedef void ( __stdcall TestClass::*PTestClassFunc1)();typedef void ( __stdcall TestClass::*PTestClassFunc2)(int parm1);typedef int ( __stdcall TestClass::*PTestClassFunc3)(int parm1,int parm2);/*这个数据结构主要是为了方便: 类函数地址、普通函数地址与数值之间的转化主要利用联合体共享内存的特征*/typedef unsigned long Addr32;typedef struct{unsigned long lAddr;unsigned long hAddr;} Addr64; typedef union _FuncPtr{Addr64 addr64; //64位地址Addr32 addr32; //32位地址//普通函数指针PFunc1 pFunc1;PFunc2 pFunc2;PFunc3 pFunc3;//特殊指针PFThisCall1 pFThisCall1;PFThisCall2 pFThisCall2;//类函数指针PTestClassFunc1 pTestClassFunc1;PTestClassFunc2 pTestClassFunc2;PTestClassFunc3 pTestClassFunc3;} FuncPtr;/* GetClassMemberFuncAddr 函数主要是为了根据任意函数地址转化为32位或64位的地址值 memberFunc:任意一个函数(普通函数或者类的函数)addr:一个32位或64位的保存函数地址值得变量*/template<typename ClassMemberFunc,typename MemberFuncAddr>void GetClassMemberFuncAddr(ClassMemberFunc memberFunc,MemberFuncAddr &addr){union{ClassMemberFunc memberFunc;MemberFuncAddr addr;} converter;//定义共享内存变量converter.memberFunc=memberFunc;addr=converter.addr;};class Base{public:Base();~Base();public:virtual void __stdcall Func1();};class Base1: public Base{public:Base1();~Base1();public:virtual void __stdcall Func1();virtual void __stdcall Func2(int param1);};class Base2: public Base{public:Base2();~Base2();public:virtual int __stdcall Func3(int param1,int parm2);};class TestClass:public Base1,public Base2{public:TestClass();~TestClass();private:int m_intVal; /* thiscall声明的类函数 其this指针不一定是在函数形参中 得看函数参数个数参数个数固定,则按stdcall方式编译参数个数不固定,则按cdecl方式编译 */public://测试虚函数//Base2 Func3重写int __stdcall Func3(int parm1,int parm2);//TestClassvirtual void __stdcall Func4();virtual void __stdcall Func5(int parm1);virtual int __stdcall Func6(int parm1,int parm2);public://测试c++默认thiscall编译的函数void ThisCall1(int parm1); //参数固定 用stdcall编译 无this形参 ecx保存thisvoid ThisCall2(int parmCount,…);//参数不固定 用cdecl编译 this指针是第一个形参public:void __stdcall Func7();void __stdcall Func8(int parm1);int __stdcall Func9(int parm1,int parm2);private:void __stdcall PrivateFunc1();

};

#include "stdafx.h"#include "TestClass.h"////////////////////////////////////////////////////////////////////////////////Base::Base(){}Base::~Base(){}void Base::Func1(){long pointerValue=(long)this;printf("Base::Func1 Run:\n this pointer=%x\n",pointerValue);}/////////////////////////////////////////////////////////////////////////////////Base1::Base1(){}Base1::~Base1(){}void Base1::Func1(){long pointerValue=(long)this;printf("Base1::Func1 Run:\n this pointer=%x\n",pointerValue);}void Base1::Func2(int parm1){long pointerValue=(long)this;printf("Base1::Func2 Run:\n this pointer=%x,parm1=%d\n",pointerValue,parm1);}////////////////////////////////////////////////////////////////////////////////Base2::Base2(){}Base2::~Base2(){}int Base2::Func3(int parm1,int parm2){long pointerValue=(long)this;printf("Base2::Func3 Run:\n this pointer=%x,parm1=%d,parm2=%d\n",pointerValue,parm1,parm2);return parm1+parm2;}////////////////////////////////////////////////////////////////////////////////TestClass::TestClass(){m_intVal=0;}TestClass::~TestClass(){}int TestClass::Func3(int parm1,int parm2){long pointerValue=(long)this;printf("Func3 Run:\n this pointer=%x,parm1=%d,parm2=%d\n",pointerValue,parm1,parm2);return parm1;}void TestClass::Func4(){int temp=m_intVal;m_intVal-=1;long pointerValue=(long)this;printf("Func4 Run:\n this pointer=%x,m_intVal=%d\n m_intVal-=1\n m_intVal=%d\n",pointerValue,temp,m_intVal);}void TestClass::Func5(int parm1){int temp=m_intVal;long pointerValue=(long)this;m_intVal=parm1;printf("Func5 Run:\n this pointer=%x,m_intVal=%d,parm1=%d\n m_intVal=parm1=%d\n",pointerValue,temp,parm1,m_intVal);}int TestClass::Func6(int parm1,int parm2){int temp=m_intVal;long pointerValue=(long)this;m_intVal=parm1-parm2;printf("Func6 Run:\n this pointer=%x,m_intVal=%d,parm1=%d,parm2=%d\n return value m_intVal=parm1-parm2=%d\n",pointerValue,temp,parm1,parm2,m_intVal);return m_intVal;}void TestClass::Func7(){int temp=m_intVal; m_intVal+=1;long pointerValue=(long)this;printf("Func7 Run:\n this pointer=%x,m_intVal=%d\n m_intVal+=1\n m_intVal=%d\n",pointerValue,temp,m_intVal);}void TestClass::Func8(int parm1){int temp=m_intVal;long pointerValue=(long)this;m_intVal-=parm1;printf("Func8 Run:\n this pointer=%x,m_intVal=%d,parm1=%d\n m_intVal-=parm1\n m_intVal=%d\n",pointerValue,temp,parm1,m_intVal);}int TestClass::Func9(int parm1,int parm2){int temp=m_intVal;long pointerValue=(long)this;m_intVal=parm1+parm2;printf("Func9 Run:\n this pointer=%x,m_intVal=%d,parm1=%d,parm2=%d\n return value m_intVal=parm1+parm2=%d\n",pointerValue,temp,parm1,parm2,m_intVal);return m_intVal;}void TestClass::ThisCall1(int parm1){int temp=m_intVal;long pointerValue=(long)this;m_intVal+=parm1;printf("ThisCall1 Run:\n this pointer=%x,m_intVal=%d,parm1=%d\n m_intVal+=parm1\n m_intVal=%d\n",pointerValue,temp,parm1,m_intVal);}void TestClass::ThisCall2(int parmCount,…){int temp=m_intVal;va_list vaptr;int i,j;va_start(vaptr,parmCount);for(i=0; i<parmCount;i++){j= va_arg(vaptr,int);m_intVal +=j;}va_end(vaptr);long pointerValue=(long)this;printf("ThisCall2 Run:\n this pointer=%x,m_intVal=%d,parmCount=%d,…\n m_intVal+=parm1+…\n m_intVal=%d\n",pointerValue,temp,parmCount,m_intVal);}void TestClass::PrivateFunc1(){long pointerValue=(long)this;printf("PrivateFunc1 Run:\n this pointer=%x",pointerValue);}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////

//执行文件

#include "stdafx.h"#include "TestClass.h"

『 不可能 』只存在於蠢人的字典里

函数编译与执行及虚函数剖析(源码论证)

相关文章:

你感兴趣的文章:

标签云: