问答文章1 问答文章501 问答文章1001 问答文章1501 问答文章2001 问答文章2501 问答文章3001 问答文章3501 问答文章4001 问答文章4501 问答文章5001 问答文章5501 问答文章6001 问答文章6501 问答文章7001 问答文章7501 问答文章8001 问答文章8501 问答文章9001 问答文章9501

对象中方法调用时,代码位置的问题

发布网友 发布时间:2022-04-25 20:10

我来回答

5个回答

热心网友 时间:2022-06-17 01:35

首先,相对于类基址来说,函数的位置是固定的,那么在VC的RTTI机制(运行时类别标识)在你定义类的时候会将你的程序中用到的类用链表的方式连接起来,当你调用用Myobject的时候,他先会去判断类,然后根据函数名利用判断得到类型的结果直接定位,RTTI具体可以去看候捷的<深入浅出MFC>中的六大仿真技术.

第二个你说的CALL ECX +18 之类的,你可以从DLL入手分析,首先你加载到程序,然后得到他的地址,那么ecx假设就是当前DLL函数偏移表的首地址,设置偏移后会得到目标函数的地址,然后执行,如果想知道他们代表什么函数,你可以选择用PEDUMP.exe,在MSDN中搜,可以搜到源码,VS中也带,主要是查看PE文件的结构,主要包括DOS头,NT头,各个区块,包括.TEXT.DATA.CODE等等区块,最重要的就是输入输出表,在输入表中有加载其它DLL的信息,当你枚举出所有加载的DLL后,每个DLL又可以查到调用的函数以及偏移地址,你可以学习一下PE文件的结构,更有助于你解决你现在的问题.PEDUMP我将它修改成GUI的.如图:

热心网友 时间:2022-06-17 01:36

虚函数,是通过虚函数表来动态定位(程序运行时候查表找到函数地址定位的)。
普通函数和成员变量是在源程序编译时候就确定了地址的。当然这个地址是相对地址。
一个PE文件(DLL 或者 EXE )文件,有个函数跳转表头( JMP 0Xxxxx),记录当前文件程序内所使用的所有函数(包括内部函数,和使用的外部导入函数),程序内部二进制机器码调用函数的地方,函数地址就是指向的这些表头的相应函数位置,二进制程序代码是固定的,而表头里面的函数实际入口地址都是在PE文件装入的时候动态设定的,这样二进制代码执行的时候就能跳转到正确的地址。
——这点,你可以通过VC调试程序,使用F11观察函数调用过程就可以看出。

ITypeLib 是类型库接口。调用成员函数是虚函数方式调用的,call [ecx+10],call [ecx+18] :ecx 里记录的虚函数表首地址,表示调用第四个第六个函数。(成员虚函数顺序是按照源码中定义顺序排列的)。

热心网友 时间:2022-06-17 01:36

对于你的问题,推荐一本书,讲的很透彻
书名:<Thinking in C++>

下面是我看这本书时的一段笔记:

C++要求在基类中声明函数时使用virtual,晚*只对virtual起作用,而且只在使用含有虚函数的基类地址时发生。仅需在声明时使用virtual。若基类中为virtual,所有的派生类中都是虚函数。在派生类中virtual的重定义称为重写。

典型的编译器对每个包含虚函数的类创建一个表(Vtable),表中放置特定类的虚函数的地址。类中秘密放置一个虚指针(VPointer),指向虚表。当通过基类指针做虚函数调用时,编译器静态的插入能取得虚指针和虚表中查找函数地址的代码,从而调用正确的函数并引起晚*。

类中不带虚函数,对象长度为期望的成员变量长度之和。若带有虚函数,则增加一个void指针长度,表明无论一个还是多个虚函数,编译器只在结构中插入单个指针。

每当创建或派生一个包含虚函数的类时,编译器为该类创建一个惟一的虚表。表中放置了类或基类中所有已声明为virtual的函数的地址。若派生类没有对基类的虚函数重新定义,就使用基类的虚函数地址,然后在类中放置虚指针,初始化为指向相应的虚表的起始地址。

当通过基类地址调用虚函数时,从基类指针开始,指向对象的起始地址。而虚指针常常在对象的开头,无论什么类型,所有的虚表都具有相同的顺序,必定知道某函数在某个位置。因为获取虚指针和实际函数地址发生在运行时,所以得到晚*。

向上类型转换仅处理地址,若编译器有一个确切类型的对象,那么对任何函数的调用不再使用晚*。
Base* pb=&dog; Base& pb1=dog; pb和pb1可能表示base地址,也可能表示派生对象的地址,必须使用虚函数。 Base pb2; pb2.f(); pb2为确切类型的对象,可以使用早*。

热心网友 时间:2022-06-17 01:37

如果是虚函数那么在调用的时候是用查表的方法,每一个类都会有自己的虚函数表.

如果是普通函数就是直接定位到内存地址的.你看到的代码是这样子的:MyObject1->IsName

在编译的时候编译器会把它转换成另外一种方式,差不多就是:类名@函数名
根据编译器的不同可能有不同,但是道理是一样的,类函数都会被转换成一个类似常量的东西,他的地址是固定的,所以在运行期可以直接定位到该函数.

LZ如果还有问题可以HI我

虚函数表里只存虚函数的内存地址,LZ应该知道什么是虚函数吧?

热心网友 时间:2022-06-17 01:38

据我所知,类经过定义,在编译的时候函数地址就相对定下来了,每个类对象的建立分配一个内存块,其中只是引用了函数的地址,你要通过地址反向解析出函数名,可能牵扯到函数描述,这个可能比较复杂,比如最新的SOA架构中,这种思想就是存在的,通过SOAP描述每个服务端存在的服务,都是通过XML来描述和解析的,但是在编译器里有没有这套机制,你就要请达人帮忙了。
声明声明:本网页内容为用户发布,旨在传播知识,不代表本网认同其观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。E-MAIL:11247931@qq.com
wps字体颜色改不了怎么办 玩lol我想走体格极端蛮王全攻击的那种符文怎么加求高手赐教 ,感激不... ...觉得不会玩,求高手赐教,个人觉得钱不够买装备,发育慢 ...加技能点,可以通地狱的,我玩的是1.11的,只为单机,求高手赐教... ...只有R技能的AD加成较高,为什么选AD呢,请高手赐教 lol小丑什么打法好(我现在用的是物攻流)出装也说说~请高手赐教~... 北京首都医科大附属附属复兴医院门诊部地址 首都医科大学附属医院首都医科大学附属复兴医院 北京复兴医院规模 求海贼王动画中所有红发香克斯的出镜 c语言main函数的位置是什么? C语言 for语句循环求N个数的最大值最小值 平均值 出现错误 C++中的函数参数有三种传递方式:值传递、指针传递和引用传递。。。 函数的参数传递指的是什么?有哪几种传递方式? c语言中函数A调用函数B,B又可以调用A? C语言有没有绝对值运算 发动机的两大机构和五大系统是什么? 发动机两大机构和五大系统是什么? 什么是发动机 的两大机构,四大系统? 发动机两大机构五大系统是什么? 汽油机的‘两大机构和五大系统’分别指的是什么? 发动机的两大机构和五大系统分别是什么? 两大机构五大系统分别是什么? 发动机的两大机构和六大系统分别是什么? iPhone8能在水里放多久? Excel 2003的数据有效性我选了序列,来源写了男,女,按了确定,为什么男女是在一排 如何在表格中设置下拉框只显示男女? excel2010中怎样用数据有效性输入性别男女 过年适合怎么做牛肉 过年 了白白患者能吃牛肉吗? C语言规定,在一个源程序中,main函数的位置( )。 函数声明的三种方式分别是什么?各有什么例子 C语言规定,在一个源程序中,main函数的位置 计算机程序常说的函数及使用的有哪些? 阴囊潮湿是什么原因? 阴囊潮湿是什么意思 男子阴囊潮湿是怎么回事?? 阴囊潮湿的危害有哪些? 有哪些VR资源比较全的平台? 求VR左右资源 知道的来 求VR百度网盘资源 在哪里可以找到 VR 资源? VR游戏及电影资源。 大哥们,谁有vr的资源,求给 谁有VR百度云资源 求左右格式的vr电影资源 残血罗刹国是风间雅的组织还是石原贵雅的?是什么? 如何找vr资源? 谁有VR资源,不是app的那种 华为手机如何同时登录两个?