CN112559094B - 一种c++模块接口的调用方法及装置 - Google Patents
一种c++模块接口的调用方法及装置 Download PDFInfo
- Publication number
- CN112559094B CN112559094B CN202011477687.XA CN202011477687A CN112559094B CN 112559094 B CN112559094 B CN 112559094B CN 202011477687 A CN202011477687 A CN 202011477687A CN 112559094 B CN112559094 B CN 112559094B
- Authority
- CN
- China
- Prior art keywords
- interface
- target
- module interface
- address
- module
- Prior art date
- Legal status (The legal status is an assumption and is not a legal conclusion. Google has not performed a legal analysis and makes no representation as to the accuracy of the status listed.)
- Active
Links
- 238000000034 method Methods 0.000 title claims abstract description 35
- 230000006870 function Effects 0.000 claims abstract description 425
- 238000006243 chemical reaction Methods 0.000 claims description 13
- 230000008569 process Effects 0.000 abstract description 9
- 230000008901 benefit Effects 0.000 abstract description 5
- 230000008859 change Effects 0.000 abstract description 4
- 210000001503 joint Anatomy 0.000 abstract 1
- 238000010586 diagram Methods 0.000 description 7
- 230000009471 action Effects 0.000 description 3
- 230000018109 developmental process Effects 0.000 description 2
- 238000005538 encapsulation Methods 0.000 description 2
- 230000004048 modification Effects 0.000 description 2
- 238000012986 modification Methods 0.000 description 2
- 238000013459 approach Methods 0.000 description 1
- 230000009286 beneficial effect Effects 0.000 description 1
- 238000004364 calculation method Methods 0.000 description 1
- 238000011161 development Methods 0.000 description 1
- 230000008140 language development Effects 0.000 description 1
- 230000000750 progressive effect Effects 0.000 description 1
- 238000012546 transfer Methods 0.000 description 1
Classifications
-
- G—PHYSICS
- G06—COMPUTING; CALCULATING OR COUNTING
- G06F—ELECTRIC DIGITAL DATA PROCESSING
- G06F9/00—Arrangements for program control, e.g. control units
- G06F9/06—Arrangements for program control, e.g. control units using stored programs, i.e. using an internal store of processing equipment to receive or retain programs
- G06F9/44—Arrangements for executing specific programs
- G06F9/448—Execution paradigms, e.g. implementations of programming paradigms
- G06F9/4482—Procedural
Landscapes
- Engineering & Computer Science (AREA)
- Software Systems (AREA)
- Theoretical Computer Science (AREA)
- Physics & Mathematics (AREA)
- General Engineering & Computer Science (AREA)
- General Physics & Mathematics (AREA)
- Stored Programmes (AREA)
Abstract
本发明提供了一种C++模块接口的调用方法及装置,在预设存储结构中定义与目标C++模块接口具有相同内存结构的对象,然后获取C++模块接口对象实例的内存地址(即指针),将之转换为在预设存储结构中定义的具有相同内存结构的对象,通过访问该对象中的数据成员,获取目标C++模块接口函数的执行地址,通过调用该执行地址完成对目标C++模块接口的调用。由于在调用目标C++模块接口的过程中不需要直接与目标C++模块接口进行对接,因此,本发明不需要对C++模块接口进行改变,在不影响C++模块接口的通用性以及面向对象的优势的基础上,实现非C++语言开发的应用程序,如Python应用程序采用非侵入方式对C++模块接口的调用。
Description
技术领域
本发明涉及计算机技术领域,更具体的,涉及一种C++模块接口的调用方法及装置。
背景技术
Python和C++是两种主流的计算机程序设计语言,被广泛应用于软件开发技术领域。
目前,采用Python开发的应用程序调用C++模块接口一般都是通过侵入式的调用方式进行的,即需要在C++模块接口的开发过程中对C++模块接口进行修改。其中,一种方法为使用Python对象封装C++模块接口,采用Python开发的应用程序调用封装后的C++模块接口。但是,封装后的C++模块接口仅能被采用Python开发的应用程序所调用,不具备通用性,而且需要对现有的C++模块进行大量改造。另一种方法为使C++模块接口修改为全部使用C语言风格的接口,使其他语言开发的应用程序均可以调用该接口。但是,这样不仅需要对现有C++模块进行改造,而且C语言风格的接口丧失了C++模块接口面向对象的优势。
发明内容
有鉴于此,本发明提供了一种C++模块接口的调用方法及装置,实现非C++语言开发的应用程序,如Python应用程序采用非侵入方式对C++模块接口的调用。
为了实现上述发明目的,本发明提供的具体技术方案如下:
一种C++模块接口的调用方法,包括:
确定目标C++模块接口的类型和内存结构;
根据所述目标C++模块接口的类型和内存结构,在预设存储结构中定义与所述目标C++模块接口具有相同内存结构的对象;
在预设存储结构中加载所述目标C++模块,获取指向所述目标C++模块的接口对象实例的内存地址,将指向所述目标C++模块的接口对象实例的内存地址转换为在预设存储结构中定义的与所述目标C++模块接口具有相同内存结构的对象实例的内存地址;
访问转换后的对象的数据成员,获取所述目标C++模块接口对象实例的函数的执行地址,通过调用该执行地址,完成对所述目标C++模块接口函数的调用。
可选的,所述根据所述目标C++模块接口的类型和内存结构,在预设存储结构中定义与所述目标C++模块接口具有相同内存结构的对象,包括:
在所述目标C++模块接口的类型为普通接口的情况下,定义一个与所述目标C++模块接口具有相同内存结构的接口对象类型,该类型在实例化后存储所述目标C++模块接口对象实例对应的内存结构中指向虚函数表对象的地址;
在预设存储结构中定义一个与所述目标C++模块接口的虚函数表具有相同内存结构的虚函数表对象类型,该类型在实例化后存储所述目标C++模块接口对象实例的成员函数的实际执行地址。
可选的,所述根据所述目标C++模块接口的类型和内存结构,在预设存储结构中定义与所述目标C++模块接口具有相同内存结构的对象,包括:
在所述目标C++模块接口的类型为单继承接口的情况下,定义一个与所述目标C++模块接口具有相同内存结构的接口对象类型,该类型在实例化后存储所述目标C++模块接口对象实例对应的内存结构中指向虚函数表对象的地址;
在预设存储结构中定义一个与所述目标C++模块接口的虚函数表具有相同内存结构的虚函数表对象类型,该类型在实例化后存储所述目标C++模块接口对象实例的成员函数的实际执行地址;单继承接口的父接口按照相同的方法进行定义。
可选的,所述根据所述目标C++模块接口的类型和内存结构,在预设存储结构中定义与所述目标C++模块接口具有相同内存结构的对象,包括:
在所述目标C++模块接口的类型为多重继承接口的情况下,定义一个与所述目标C++模块接口具有相同内存结构的接口对象类型,该类型在实例化后存储所述目标C++模块接口对象实例对应的内存结构中指向所有父接口的虚函数表对象的地址,其中,所述目标C++模块接口与第一个继承的父接口共用同一个虚函数表;
在预设存储结构中定义一个与所述目标C++模块接口的虚函数表具有相同内存结构的虚函数表对象类型,该类型在实例化后存储所述目标C++模块接口对象实例的成员函数的实际执行地址;
多重继承接口的所有父接口按照相同的方法进行定义。
可选的,所述根据所述目标C++模块接口的类型和内存结构,在预设存储结构中定义与所述目标C++模块接口具有相同内存结构的对象,包括:
在所述目标C++模块接口的类型为单虚继承接口的情况下,定义一个与所述目标C++模块接口具有相同内存结构的接口对象类型,该类型在实例化后存储所述目标C++模块接口对象实例对应的内存结构中指向虚函数表对象的地址、指向虚基址表对象的地址以及指向父接口的虚函数表对象的地址,所述目标C++模块接口的虚函数与父接口的虚函数表不共用;
在预设存储结构中定义一个与所述目标C++模块接口的虚基址表具有相同内存结构的虚基址表对象类型,该类型在实例化后存储所述目标C++模块接口进行接口类型转换的寻址偏移量;
单虚继承接口所继承的父接口使用相同的方式进行定义。
可选的,所述根据所述目标C++模块接口的类型和内存结构,在预设存储结构中定义与所述目标C++模块接口具有相同内存结构的对象,包括:
在所述目标C++模块接口的类型为多重虚继承接口的情况下,定义一个与所述目标C++模块接口具有相同内存结构的接口对象类型,该类型在实例化后存储所述目标C++模块接口对象实例对应的内存结构中指向虚函数表对象的地址、指向虚基址表对象的地址以及指向所有父接口的虚函数表对象的地址,所述目标C++模块接口的虚函数表与父接口的虚函数表不共用;
在预设存储结构中定义一个与所述目标C++模块接口的虚基址表具有相同内存结构的虚基址表对象类型,该类型在实例化后存储所述目标C++模块接口进行接口类型转换的寻址偏移量;
多重虚继承接口所继承的父接口使用相同的方式进行定义。
可选的,所述根据所述目标C++模块接口的类型,在预设存储结构中定义与所述目标C++模块接口具有相同内存结构的对象,包括:
在所述目标C++模块接口的类型为回调接口的情况下,定义一个与所述目标C++模块接口具有相同内存结构的接口对象类型,该类型在实例化后存储指向虚函数表的地址,由调用者进行实例化,实例化时填充指向虚函数表对象实例的地址;
在预设存储结构中定义与所述目标C++接口的虚函数表具有相同内存结构的虚函数表对象类型,该类型在实例化后存储所述目标C++接口的函数实际指向地址,由调用者进行实例化,实例化时填充实际的执行地址。
可选的,预设存储结构为调用者程序运行的内存空间。
可选的,所述获取所述目标C++模块接口对象实例的函数的执行地址,包括:
在所述C++模块接口的类型为普通接口的情况下,使用指向虚函数表的地址从虚函数表中获取所述目标C++模块接口对象实例的函数的执行地址。
可选的,所述获取所述目标C++模块接口对象实例的函数的执行地址,包括:
在所述C++模块接口的类型为单继承接口的情况下,使用指向虚函数表的地址从虚函数表中获取所述目标C++模块接口对象实例的函数和父接口函数的执行地址。
可选的,所述获取所述目标C++模块接口对象实例的函数的执行地址,包括:
在所述C++模块接口的类型为多重继承接口的情况下,使用指向第一个虚函数表的地址从虚函数表中获取所述目标C++模块接口对象实例的函数和第一个父接口函数的执行地址;
使用指向第二个虚函数表的地址从虚函数表中获取第二个父接口函数的执行地址,依此类推。
可选的,所述获取所述目标C++模块接口对象实例的函数的执行地址,包括:
在所述C++模块接口的类型为单虚继承接口的情况下,使用指向第一个虚函数表的地址从虚函数表中获取所述目标C++模块接口对象实例的函数的执行地址;
使用指向第二个虚函数表的地址从虚函数表中获取父接口函数的执行地址。
可选的,所述获取所述目标C++模块接口对象实例的函数的执行地址,包括:
在所述C++模块接口的类型为多重虚继承接口的情况下,使用指向第一个虚函数表的地址从虚函数表中获取所述目标C++模块接口对象实例的函数的执行地址;
使用指向第二个虚函数表的地址从虚函数表中获取第一个父接口函数的执行地址;
使用指向第三个虚函数表的地址从虚函数表中获取第二个父接口函数的执行地址,依此类推。
一种C++模块接口的调用装置,包括:
接口类型确定单元,用于确定目标C++模块接口的类型和内存结构;
对象定义单元,用于根据所述目标C++模块接口的类型和内存结构,在预设存储结构中定义与所述目标C++模块接口具有相同内存结构的对象;
实例转换单元,在预设存储结构中加载所述目标C++模块,获取指向所述目标C++模块接口对象实例的地址,将指向所述目标C++模块接口对象实例的内存地址转换为指向在预设存储结构中定义的与所述目标C++模块接口具有相同内存结构的对象实例的内存地址;
函数调用单元,用于访问转换后的对象的数据成员,获取所述目标C++模块接口对象实例的函数的执行地址,通过调用该执行地址,完成对所述目标C++模块接口函数的调用。
可选的,所述对象定义单元,具体用于:
在所述目标C++模块接口的类型为普通接口的情况下,定义一个与所述目标C++模块接口具有相同内存结构的接口对象类型,该类型在实例化后存储所述目标C++模块接口对象实例对应的内存结构中指向虚函数表对象的地址;
在预设存储结构中定义一个与所述目标C++模块接口的虚函数表具有相同内存结构的虚函数表对象类型,该类型在实例化后存储所述目标C++模块接口对象实例的成员函数的实际执行地址。
可选的,所述对象定义单元,具体用于:
在所述目标C++模块接口的类型为单继承接口的情况下,定义一个与所述目标C++模块接口具有相同内存结构的接口对象类型,该类型在实例化后存储所述目标C++模块接口对象实例对应的内存结构中指向虚函数表对象的地址;
在预设存储结构中定义一个与所述目标C++模块接口的虚函数表具有相同内存结构的虚函数表对象类型,该类型在实例化后存储所述目标C++模块接口对象实例的成员函数的实际执行地址;单继承接口的父接口按照相同的方法进行定义。
可选的,所述对象定义单元,具体用于:
在所述目标C++模块接口的类型为多重继承接口的情况下,定义一个与所述目标C++模块接口具有相同内存结构的接口对象类型,该类型在实例化后存储所述目标C++模块接口对象实例对应的内存结构中指向所有父接口的虚函数表对象的地址,其中,所述目标C++模块接口与第一个继承的父接口共用同一个虚函数表;
在预设存储结构中定义一个与所述目标C++模块接口的虚函数表具有相同内存结构的虚函数表对象类型,该类型在实例化后存储所述目标C++模块接口对象实例的成员函数的实际执行地址;
多重继承接口的所有父接口按照相同的方法进行定义。
可选的,所述对象定义单元,具体用于:
在所述目标C++模块接口的类型为单虚继承接口的情况下,定义一个与所述目标C++模块接口具有相同内存结构的接口对象类型,该类型在实例化后存储所述目标C++模块接口对象实例对应的内存结构中指向虚函数表对象的地址、指向虚基址表对象的地址以及指向父接口的虚函数表对象的地址,所述目标C++模块接口的虚函数与父接口的虚函数表不共用;
在预设存储结构中定义一个与所述目标C++模块接口的虚基址表具有相同内存结构的虚基址表对象类型,该类型在实例化后存储所述目标C++模块接口进行接口类型转换的寻址偏移量;
单虚继承接口所继承的父接口使用相同的方式进行定义。
可选的,所述对象定义单元,具体用于:
在所述目标C++模块接口的类型为多重虚继承接口的情况下,定义一个与所述目标C++模块接口具有相同内存结构的接口对象类型,该类型在实例化后存储所述目标C++模块接口对象实例对应的内存结构中指向虚函数表对象的地址、指向虚基址表对象的地址以及指向所有父接口的虚函数表对象的地址,所述目标C++模块接口的虚函数表与父接口的虚函数表不共用;
在预设存储结构中定义一个与所述目标C++模块接口的虚基址表具有相同内存结构的虚基址表对象类型,该类型在实例化后存储所述目标C++模块接口进行接口类型转换的寻址偏移量;
多重虚继承接口所继承的父接口使用相同的方式进行定义。
可选的,所述对象定义单元,具体用于:
在所述目标C++模块接口的类型为回调接口的情况下,定义一个与所述目标C++模块接口具有相同内存结构的接口对象类型,该类型在实例化后存储指向虚函数表的地址,由调用者进行实例化,实例化时填充指向虚函数表对象实例的地址;
在预设存储结构中定义与所述目标C++接口的虚函数表具有相同内存结构的虚函数表对象类型,该类型在实例化后存储所述目标C++接口的函数实际指向地址,由调用者进行实例化,实例化时填充实际的执行地址。
可选的,所述函数调用单元,具体用于:在所述C++模块接口的类型为普通接口的情况下,使用指向虚函数表的地址从虚函数表中获取所述目标C++模块接口对象实例的函数的执行地址。
可选的,所述函数调用单元,具体用于:在所述C++模块接口的类型为单继承接口的情况下,使用指向虚函数表的地址从虚函数表中获取所述目标C++模块接口对象实例的函数和父接口函数的执行地址。
可选的,所述函数调用单元,具体用于:
在所述C++模块接口的类型为多重继承接口的情况下,使用指向第一个虚函数表的地址从虚函数表中获取所述目标C++模块接口对象实例的函数和第一个父接口函数的执行地址;
使用指向第二个虚函数表的地址从虚函数表中获取第二个父接口函数的执行地址,依此类推。
可选的,所述函数调用单元,具体用于:
在所述C++模块接口的类型为单虚继承接口的情况下,使用指向第一个虚函数表的地址从虚函数表中获取所述目标C++模块接口对象实例的函数的执行地址;
使用指向第二个虚函数表的地址从虚函数表中获取父接口函数的执行地址。
可选的,所述函数调用单元,具体用于:
在所述C++模块接口的类型为多重虚继承接口的情况下,使用指向第一个虚函数表的地址从虚函数表中获取所述目标C++模块接口对象实例的函数的执行地址;
使用指向第二个虚函数表的地址从虚函数表中获取第一个父接口函数的执行地址;
使用指向第三个虚函数表的地址从虚函数表中获取第二个父接口函数的执行地址,依此类推。
相对于现有技术,本发明的有益效果如下:
本发明提供了一种C++模块接口的调用方法及装置,在预设存储结构中定义与目标C++模块接口具有相同内存结构的对象,然后获取C++模块接口对象的内存地址,将之转换为在预设存储结构中定义的具有相同内存结构的对象,通过访问该对象中的数据成员,获取目标C++模块接口函数的执行地址,通过调用该执行地址完成对目标C++模块接口的调用。由于在调用C++模块接口的过程中不需要直接与C++模块接口进行对接,因此,本发明不需要对C++模块接口进行改变,在不影响C++模块接口的通用性以及面向对象的优势的基础上,实现非C++语言开发的应用程序,如Python应用程序采用非侵入方式对C++模块接口的调用。
附图说明
为了更清楚地说明本发明实施例或现有技术中的技术方案,下面将对实施例或现有技术描述中所需要使用的附图作简单地介绍,显而易见地,下面描述中的附图仅仅是本发明的实施例,对于本领域普通技术人员来讲,在不付出创造性劳动的前提下,还可以根据提供的附图获得其他的附图。
图1为本发明实施例公开的一种C++模块接口的调用方法的流程示意图;
图2为本发明实施例公开的一种普通接口的内存结构示意图;
图3为本发明实施例公开的一种单继承接口的内存结构示意图;
图4为本发明实施例公开的一种多重继承接口的内存结构示意图;
图5为本发明实施例公开的一种单虚继承接口的内存结构示意图;
图6为本发明实施例公开的一种多重虚继承接口的内存结构示意图;
图7为本发明实施例公开的一种C++模块接口的调用装置的结构示意图。
具体实施方式
下面将结合本发明实施例中的附图,对本发明实施例中的技术方案进行清楚、完整地描述,显然,所描述的实施例仅仅是本发明一部分实施例,而不是全部的实施例。基于本发明中的实施例,本领域普通技术人员在没有做出创造性劳动前提下所获得的所有其他实施例,都属于本发明保护的范围。
发明人研究发现:在基于C++抽象类的方式定义C++模块接口,并实现C++定义的接口模块之后,C++编译器将C++定义的接口翻译成一个结构体,该结构体的内存结构中包括一个指向该接口的虚函数表的指针,即指向虚函数表的地址,虚函数表中存放了按照函数声明顺序记录的JMP跳转指令,指向实际的函数执行地址。调用者调用接口中的某个函数时,需要按照调用约定将函数参数压栈或写入寄存器,然后调用虚函数表中对应函数的JMP跳转指令执行实际的函数实现逻辑。因此,只需要在非C++开发的应用程序,如Python应用程序中定义与C++模块接口具有相同内存结构的对象,获取C++模块接口函数的实际执行地址,即可实现非C++语言开发的应用程序,如Python应用程序采用非侵入方式对C++模块接口的调用。
在此基础上,本实施例公开了一种C++模块接口的调用方法,应用于部署有非C++语言,如Python开发的应用程序的设备,请参阅图1,该方法具体包括以下步骤:
S101:确定目标C++模块接口的类型和内存结构;
S102:根据目标C++模块接口的类型和内存结构,在预设存储结构中定义与目标C++模块接口具有相同内存结构的对象;
预设存储结构为调用者程序运行的内存空间,如栈或堆内存。
S103:在预设存储结构中加载目标C++模块,获取指向目标C++模块的接口对象实例的内存地址,将指向目标C++模块的接口对象实例的内存地址转换为在预设存储结构中定义的与目标C++模块接口具有相同内存结构的对象实例的内存地址;
S104:访问转换后的对象的数据成员,获取目标C++模块接口对象实例的函数的执行地址,通过调用该执行地址,完成对目标C++模块接口函数的调用。
C++模块接口的类型包括:普通接口、单继承接口、多重继承接口、虚继承接口、多重虚继承接口和回调接口。以下分别进行举例说明:
一、普通接口
假设有以下一个普通接口:
上述普通接口的内存结构如图2所示,接口ITestBase实例化时,由操作系统根据该接口的大小分配一块内存存储,该内存的+0(即偏移位置)位置存储的是该接口的虚函数表地址,该虚函数表地址指向一个内存中的虚函数表,该虚函数表的0号位置(表索引)存放指向接口成员函数func01的执行地址, 1号位置存放指向接口成员函数Add的执行地址,2号位置存放指向接口成员函数release的执行地址。
为了获得上述类型为普通接口类型的函数执行地址,首先在预设存储结构中定义一个与目标C++模块接口具有相同内存结构的接口对象类型,其次获取目标C++模块接口实例的内存地址(即指针),将之转换为指向在预设存储结构中定义的对象类型的内存地址,该地址+0偏移量的位置即为该接口的虚函数表对象地址,通过目标函数在虚函数表中的位置序号获取目标函数的实际执行地址,调用该地址即可执行目标函数。
以Python应用程序为例,定义与上述类型为普通接口的目标C++模块接口具有相同内存结构的对象如下:
二、单继承接口
在目标C++模块接口的类型为单继承接口的情况下,定义一个与目标C++模块接口具有相同内存结构的接口对象类型,该类型在实例化后存储目标C++模块接口对象实例对应的内存结构中指向虚函数表对象的地址。
在预设存储结构中定义一个与目标C++模块接口的虚函数表具有相同内存结构的虚函数表对象类型,该类型在实例化后存储所述目标C++模块接口对象实例的成员函数的实际执行地址;单继承接口的父接口按照相同的方法进行定义。
在预设存储结构中加载目标C++模块,获取指向目标C++模块的接口对象实例的内存地址,将指向目标C++模块的接口对象实例的内存地址转换为在预设存储结构中定义的与目标C++模块接口具有相同内存结构的对象实例的内存地址。访问转换后的对象的数据成员,使用指向虚函数表的地址从虚函数表中获取目标C++模块接口对象实例的函数和父接口函数的执行地址。通过调用该执行地址,完成对目标C++模块接口函数的调用。
以下为单继承的接口定义示例:
其中,ITestBase的接口定义在上文中已详细介绍,在此不再赘述。
ITestBase的接口的内存结构图3所示,其中接口ITestDerive即为单继承的接口,它继承于接口ITestBase,并且新增了一个函数func02。从图3中可以看出,它与继承接口共用了同一张虚函数表。因此,在Python中,同样可以使用继承语法对ITestDerive的虚函数表进行封装:
首先对C++的ITestDerive接口的虚函数表进行封装为ITestDeriveVftbl,它使用了Python的继承语法,从ITestBaseVftbl继承;其次对C++的ITestDerive接口进行封装,其内存结构只有一个指向虚函数表ITestDeriveVftbl的地址vfptr;最后对C++的ITestDerive接口提供的函数进行封装,根据虚函数表中函数地址调用C++的接口函数。
三、多重继承接口
在目标C++模块接口的类型为多重继承接口的情况下,定义一个与目标C++模块接口具有相同内存结构的接口对象类型,该类型在实例化后存储目标C++模块接口对象实例对应的内存结构中指向所有父接口的虚函数表对象的地址,其中,目标C++模块接口与第一个继承的父接口共用同一个虚函数表;
在预设存储结构中定义一个与目标C++模块接口的虚函数表具有相同内存结构的虚函数表对象类型,该类型在实例化后存储目标C++模块接口对象实例的成员函数的实际执行地址;多重继承接口的所有父接口按照相同的方法进行定义。
在预设存储结构中加载目标C++模块,获取指向目标C++模块的接口对象实例的内存地址,将指向目标C++模块的接口对象实例的内存地址转换为在预设存储结构中定义的与目标C++模块接口具有相同内存结构的对象实例的内存地址。通过访问转换后的对象的数据成员,使用指向第一个虚函数表的地址从虚函数表中获取目标C++模块接口对象实例的函数和第一个父接口函数的执行地址;使用指向第二个虚函数表的地址从虚函数表中获取第二个父接口函数的执行地址,依此类推。通过调用该执行地址,完成对目标C++模块接口函数的调用。
多重继承的接口的封装示例如下:
ITestMultiDerive为多重继承的接口,它的内存结构如图4所示,其中,多重继承与单继承的区别在于,ITestMultiDerive与第一个继承接口ITestBase共用同一张虚函数表,后面的继承接口使用单独的虚函数表存储。
使用Python进行封装的定义如下:
/>
/>
首先将各个接口的虚函数表封装为Python的结构类型,C++接口ITestBaseEx的虚函数表对应Python的ITestBaseExVftbl类型,ITestBaseExVftbl类型中的每个成员为C++接口ITestBaseEx的每个成员函数的执行地址,带多重继承的C++接口ITestMultiDerive的虚函数表对应Python的ITestMultiDeriveVftbl类型,ITestMultiDeriveVftbl类型从ITestBaseVftbl继承,它的每个成员为C++接口ITestMultiDerive的成员函数的执行地址;其次将带多重继承的C++接口ITestMultiDerive封装为Python的结构类型ITestMultiDerive,其内存结构中仅包含两个虚函数表地址,vfptrBase为指向ITestMultiDeriveVftbl类型的地址,vfptrBaseEx为指向ITestBaseExVftbl类型的地址;最后对C++接口ITestMultiDerive的成员函数进行封装,其中函数func02是从ITestBaseEx接口中继承的,因此,需要从vfptrBaseEx中获取函数执行地址。
四、单虚继承接口
假设有以下一个虚继承接口:
上述虚继承接口的内存结构如图5所示,内存结构除了一个指向自身虚函数表(vftable)的指针外,还有一个指向虚基址表(vbtable)的指针、一个指向父接口虚函数表的指针。
以ITestVirtualDerive的定义为例,它在内存中的实例的+0B位置存放的是指向自身虚函数表的内存地址,该虚函数表不含父接口的函数执行地址。
+8B位置存放的是指向虚基址表的地址(这里的+8B是指一个指针类型的存储在64位程序中占用了8个字节,如在32位程序中,一个指针的长度为4个字节,此处偏移量为+4B)。这里的虚基址表存放了虚基址表地址相对于各个父接口和自身的偏移量。用于类型的转换。
当需要执行本接口提供的函数时,使用+0B位置的虚函数表获取目标函数的执行地址;
当需要执行父接口提供的函数时,使用+8B位置的虚基址表获取目标接口的内存地址,然后再从其虚函数表中获取目标函数的执行地址;
比如,当需要执行ITestBase::Add函数时,计算过程如下:
1、已知ITestVirtualDerive的实例的内存地址,假设为a
2、a+8B的位置为虚基址表地址,假设为VBPTR
3、ITestBase接口为ITestVirtualDerive的唯一父接口,其地址偏移量在VBPTR的1号位置,记为VBPTR[1]
4、那么ITestBase的内存地址为a+8B+VBPTR[1],假设为b,即b=a+8B+VBPTR[1]
5、将内存地址b指向的接口类型ITestBase进行普通接口类型的转换,其b+0B的位置即为ITestBase接口的虚函数表地址,记为VFPTR,则VFPTR=b+0B
6、ITestBase::Add函数在接口ITestBase的虚函数表中的序号为1,则其实际的函数执行地址即为:VFPTR[1]
调用VFPTR[1],即为执行了ITestBase::Add函数。
因此,为了获得上述类型为虚继承接口类型的函数执行地址,首先在预设存储结构定义与目标C++模块接口具有相同内存结构的对象类型,其次获取目标C++模块接口实例的内存地址(即指针),将之转换为指向在预设存储结构中定义的对象类型的内存地址,使用该地址+0B偏移量位置访问自身接口的虚函数表,使用该地址+8B偏移量位置访问虚基址表,根据虚基址表中的偏移量计算指向父接口虚函数表的地址,根据目标函数在虚函数表中的序号,获得目标函数的实际执行地址,调用该执行地址即可执行目标函数。
以Python应用程序为例,定义与上述类型为虚继承接口的目标C++模块接口具有相同内存结构的对象如下:
五、多重虚继承接口
在目标C++模块接口的类型为多重虚继承接口的情况下,定义一个与目标C++模块接口具有相同内存结构的接口对象类型,该类型在实例化后存储目标C++模块接口对象实例对应的内存结构中指向虚函数表对象的地址、指向虚基址表对象的地址以及指向所有父接口的虚函数表对象的地址,目标C++模块接口的虚函数表与父接口的虚函数表不共用。
在预设存储结构中定义一个与目标C++模块接口的虚基址表具有相同内存结构的虚基址表对象类型,该类型在实例化后存储目标C++模块接口进行接口类型转换的寻址偏移量,多重虚继承接口所继承的父接口使用相同的方式进行定义。
在预设存储结构中加载目标C++模块,获取指向目标C++模块的接口对象实例的内存地址,将指向目标C++模块的接口对象实例的内存地址转换为在预设存储结构中定义的与目标C++模块接口具有相同内存结构的对象实例的内存地址。通过访问转换后的对象的数据成员,使用指向第一个虚函数表的地址从虚函数表中获取目标C++模块接口对象实例的函数的执行地址;使用指向第二个虚函数表的地址从虚函数表中获取第一个父接口函数的执行地址;使用指向第三个虚函数表的地址从虚函数表中获取第二个父接口函数的执行地址,依此类推。通过调用该执行地址,完成对目标C++模块接口函数的调用。
C++多重虚继承的接口定义示例如下:
ITestMultiVirtualDerive从ITestBase和ITestBaseEx接口虚继承,其内存结构如图6所示,ITestMultiVirtualDerive的内存结构包含一个指向自身虚函数表的地址,一个指向虚基址表的地址,指向继承接口ITestBase的虚函数表的地址以及指向继承接口ITestBaseEx的虚函数表地址需要根据虚基址表存放的偏移量进行计算。
因此,使用Python可对ITestMultiVirtualDerive接口进行如下封装:
/>
ITestMultiVirtualDerive从不同的虚函数表地址中获取实际的函数执行地址并执行相应的函数。
六、回调接口
回调接口是指由被调用者定义,而由调用者实现的接口,假设有以下一个回调接口:
/>
其中的ITestCallback是由C++定义的,当非C++语言,如Python调用ITestCallbackMgr接口时,需要实现ITestCallback接口,本实施例中Python的实现方式就是按照C++接口的内存结构定义结构ITestCallback,并填充合适的值,即合适的函数执行地址。
为了能够向目标C++模块接口传递由目标C++模块定义的回调接口,首先在预设存储结构中定义与上述类型为回调接口的目标C++模块接口具有相同内存结构的对象类型,其次该对象类型由调用者进行实例化时,创建虚函数表,填充每个函数的实际执行地址,并填充指向虚函数表的地址,然后将指向该对象类型的内存地址作为函数参数传递给目标C++模块接口的函数,目标C++模块接口在执行过程中将之视为其定义的回调接口类型,调用回调接口的函数。
以Python应用程序为例,创建与上述类型为回调接口的目标C++模块接口具有相同内存结构的对象如下:
/>
可见,本实施例公开的一种C++模块接口的调用方法,在预设存储结构中定义与目标C++模块接口具有相同内存结构的对象,然后获取C++模块接口对象的内存地址,将之转换为在预设存储结构中定义的具有相同内存结构的对象,通过访问该对象中的数据成员,获取目标C++模块接口函数的执行地址,通过调用该执行地址完成对目标C++模块接口的调用。由于在调用C++模块接口的过程中不需要直接与C++模块接口进行对接,因此,本发明不需要对C++模块接口进行改变,在不影响C++模块接口的通用性以及面向对象的优势的基础上,实现非C++语言开发的应用程序,如Python应用程序采用非侵入方式对C++模块接口的调用。
基于上述实施例公开的一种C++模块接口的调用方法,本实施例对应公开了一种C++模块接口的调用装置,请参阅图7,该装置包括:
接口类型确定单元100,用于确定目标C++模块接口的类型和内存结构;
对象定义单元200,用于根据所述目标C++模块接口的类型和内存结构,在预设存储结构中定义与所述目标C++模块接口具有相同内存结构的对象;
实例转换单元300,在预设存储结构中加载所述目标C++模块,获取指向所述目标C++模块接口对象实例的地址,将指向所述目标C++模块接口对象实例的内存地址转换为指向在预设存储结构中定义的与所述目标C++模块接口具有相同内存结构的对象实例的内存地址;
函数调用单元400,用于访问转换后的对象的数据成员,获取所述目标C++模块接口对象实例的函数的执行地址,通过调用该执行地址,完成对所述目标C++模块接口函数的调用。
可选的,所述对象定义单元200,具体用于:
在所述目标C++模块接口的类型为普通接口的情况下,定义一个与所述目标C++模块接口具有相同内存结构的接口对象类型,该类型在实例化后存储所述目标C++模块接口对象实例对应的内存结构中指向虚函数表对象的地址;
在预设存储结构中定义一个与所述目标C++模块接口的虚函数表具有相同内存结构的虚函数表对象类型,该类型在实例化后存储所述目标C++模块接口对象实例的成员函数的实际执行地址。
可选的,所述对象定义单元200,具体用于:
在所述目标C++模块接口的类型为单继承接口的情况下,定义一个与所述目标C++模块接口具有相同内存结构的接口对象类型,该类型在实例化后存储所述目标C++模块接口对象实例对应的内存结构中指向虚函数表对象的地址;
在预设存储结构中定义一个与所述目标C++模块接口的虚函数表具有相同内存结构的虚函数表对象类型,该类型在实例化后存储所述目标C++模块接口对象实例的成员函数的实际执行地址;单继承接口的父接口按照相同的方法进行定义。
可选的,所述对象定义单元200,具体用于:
在所述目标C++模块接口的类型为多重继承接口的情况下,定义一个与所述目标C++模块接口具有相同内存结构的接口对象类型,该类型在实例化后存储所述目标C++模块接口对象实例对应的内存结构中指向所有父接口的虚函数表对象的地址,其中,所述目标C++模块接口与第一个继承的父接口共用同一个虚函数表;
在预设存储结构中定义一个与所述目标C++模块接口的虚函数表具有相同内存结构的虚函数表对象类型,该类型在实例化后存储所述目标C++模块接口对象实例的成员函数的实际执行地址;
多重继承接口的所有父接口按照相同的方法进行定义。
可选的,所述对象定义单元200,具体用于:
在所述目标C++模块接口的类型为单虚继承接口的情况下,定义一个与所述目标C++模块接口具有相同内存结构的接口对象类型,该类型在实例化后存储所述目标C++模块接口对象实例对应的内存结构中指向虚函数表对象的地址、指向虚基址表对象的地址以及指向父接口的虚函数表对象的地址,所述目标C++模块接口的虚函数与父接口的虚函数表不共用;
在预设存储结构中定义一个与所述目标C++模块接口的虚基址表具有相同内存结构的虚基址表对象类型,该类型在实例化后存储所述目标C++模块接口进行接口类型转换的寻址偏移量;
单虚继承接口所继承的父接口使用相同的方式进行定义。
可选的,所述对象定义单元200,具体用于:
在所述目标C++模块接口的类型为多重虚继承接口的情况下,定义一个与所述目标C++模块接口具有相同内存结构的接口对象类型,该类型在实例化后存储所述目标C++模块接口对象实例对应的内存结构中指向虚函数表对象的地址、指向虚基址表对象的地址以及指向所有父接口的虚函数表对象的地址,所述目标C++模块接口的虚函数表与父接口的虚函数表不共用;
在预设存储结构中定义一个与所述目标C++模块接口的虚基址表具有相同内存结构的虚基址表对象类型,该类型在实例化后存储所述目标C++模块接口进行接口类型转换的寻址偏移量;
多重虚继承接口所继承的父接口使用相同的方式进行定义。
可选的,所述对象定义单元200,具体用于:
在所述目标C++模块接口的类型为回调接口的情况下,定义一个与所述目标C++模块接口具有相同内存结构的接口对象类型,该类型在实例化后存储指向虚函数表的地址,由调用者进行实例化,实例化时填充指向虚函数表对象实例的地址;
在预设存储结构中定义与所述目标C++接口的虚函数表具有相同内存结构的虚函数表对象类型,该类型在实例化后存储所述目标C++接口的函数实际指向地址,由调用者进行实例化,实例化时填充实际的执行地址。
可选的,所述函数调用单元400,具体用于:在所述C++模块接口的类型为普通接口的情况下,使用指向虚函数表的地址从虚函数表中获取所述目标C++模块接口对象实例的函数的执行地址。
可选的,所述函数调用单元400,具体用于:在所述C++模块接口的类型为单继承接口的情况下,使用指向虚函数表的地址从虚函数表中获取所述目标C++模块接口对象实例的函数和父接口函数的执行地址。
可选的,所述函数调用单元400,具体用于:
在所述C++模块接口的类型为多重继承接口的情况下,使用指向第一个虚函数表的地址从虚函数表中获取所述目标C++模块接口对象实例的函数和第一个父接口函数的执行地址;
使用指向第二个虚函数表的地址从虚函数表中获取第二个父接口函数的执行地址,依此类推。
可选的,所述函数调用单元400,具体用于:
在所述C++模块接口的类型为单虚继承接口的情况下,使用指向第一个虚函数表的地址从虚函数表中获取所述目标C++模块接口对象实例的函数的执行地址;
使用指向第二个虚函数表的地址从虚函数表中获取父接口函数的执行地址。
可选的,所述函数调用单元400,具体用于:
在所述C++模块接口的类型为多重虚继承接口的情况下,使用指向第一个虚函数表的地址从虚函数表中获取所述目标C++模块接口对象实例的函数的执行地址;
使用指向第二个虚函数表的地址从虚函数表中获取第一个父接口函数的执行地址;
使用指向第三个虚函数表的地址从虚函数表中获取第二个父接口函数的执行地址,依此类推。
本实施例提供了一种C++模块接口的调用装置,在预设存储结构中定义与目标C++模块接口具有相同内存结构的对象,然后获取C++模块接口对象的内存地址,将之转换为在预设存储结构中定义的具有相同内存结构的对象,通过访问该对象中的数据成员,获取目标C++模块接口函数的执行地址,通过调用该执行地址完成对目标C++模块接口的调用。由于在调用C++模块接口的过程中不需要直接与C++模块接口进行对接,因此,本发明不需要对C++模块接口进行改变,在不影响C++模块接口的通用性以及面向对象的优势的基础上,实现非C++语言开发的应用程序,如Python应用程序采用非侵入方式对C++模块接口的调用。
本说明书中各个实施例采用递进的方式描述,每个实施例重点说明的都是与其他实施例的不同之处,各个实施例之间相同相似部分互相参见即可。对于实施例公开的装置而言,由于其与实施例公开的方法相对应,所以描述的比较简单,相关之处参见方法部分说明即可。
还需要说明的是,在本文中,诸如第一和第二等之类的关系术语仅仅用来将一个实体或者操作与另一个实体或操作区分开来,而不一定要求或者暗示这些实体或操作之间存在任何这种实际的关系或者顺序。而且,术语“包括”、“包含”或者其任何其他变体意在涵盖非排他性的包含,从而使得包括一系列要素的过程、方法、物品或者设备不仅包括那些要素,而且还包括没有明确列出的其他要素,或者是还包括为这种过程、方法、物品或者设备所固有的要素。在没有更多限制的情况下,由语句“包括一个……”限定的要素,并不排除在包括所述要素的过程、方法、物品或者设备中还存在另外的相同要素。
结合本文中所公开的实施例描述的方法或算法的步骤可以直接用硬件、处理器执行的软件模块,或者二者的结合来实施。软件模块可以置于随机存储器(RAM)、内存、只读存储器(ROM)、电可编程ROM、电可擦除可编程ROM、寄存器、硬盘、可移动磁盘、CD-ROM、或技术领域内所公知的任意其它形式的存储介质中。
上述各个实施例之间可任意组合,对所公开的实施例的上述说明,本说明书中各实施例中记载的特征可以相互替换或者组合,使本领域专业技术人员能够实现或使用本申请。
对所公开的实施例的上述说明,使本领域专业技术人员能够实现或使用本发明。对这些实施例的多种修改对本领域的专业技术人员来说将是显而易见的,本文中所定义的一般原理可以在不脱离本发明的精神或范围的情况下,在其它实施例中实现。因此,本发明将不会被限制于本文所示的这些实施例,而是要符合与本文所公开的原理和新颖特点相一致的最宽的范围。
Claims (9)
1.一种C++模块接口的调用方法,其特征在于,包括:
确定目标C++模块接口的类型和内存结构;
根据所述目标C++模块接口的类型和内存结构,在预设存储结构中定义与所述目标C++模块接口具有相同内存结构的对象;
在预设存储结构中加载所述目标C++模块,获取指向所述目标C++模块的接口对象实例的内存地址,将指向所述目标C++模块的接口对象实例的内存地址转换为在预设存储结构中定义的与所述目标C++模块接口具有相同内存结构的对象实例的内存地址;
访问转换后的与所述目标C++模块接口具有相同内存结构的对象的数据成员,获取所述目标C++模块接口对象实例的函数的执行地址,通过调用该执行地址,完成对所述目标C++模块接口函数的调用;
其中,所述获取所述目标C++模块接口对象实例的函数的执行地址,包括:
在所述C++模块接口的类型为普通接口的情况下,使用指向虚函数表的地址从虚函数表中获取所述目标C++模块接口对象实例的函数的执行地址;或,
所述获取所述目标C++模块接口对象实例的函数的执行地址,包括:
在所述C++模块接口的类型为单继承接口的情况下,使用指向虚函数表的地址从虚函数表中获取所述目标C++模块接口对象实例的函数和父接口函数的执行地址;或,
所述获取所述目标C++模块接口对象实例的函数的执行地址,包括:
在所述C++模块接口的类型为多重继承接口的情况下,使用指向第一个虚函数表的地址从虚函数表中获取所述目标C++模块接口对象实例的函数和第一个父接口函数的执行地址;
使用指向第二个虚函数表的地址从虚函数表中获取第二个父接口函数的执行地址,依此类推;或,
所述获取所述目标C++模块接口对象实例的函数的执行地址,包括:
在所述C++模块接口的类型为单虚继承接口的情况下,使用指向第一个虚函数表的地址从虚函数表中获取所述目标C++模块接口对象实例的函数的执行地址;
使用指向第二个虚函数表的地址从虚函数表中获取父接口函数的执行地址;或,
所述获取所述目标C++模块接口对象实例的函数的执行地址,包括:
在所述C++模块接口的类型为多重虚继承接口的情况下,使用指向第一个虚函数表的地址从虚函数表中获取所述目标C++模块接口对象实例的函数的执行地址;
使用指向第二个虚函数表的地址从虚函数表中获取第一个父接口函数的执行地址;
使用指向第三个虚函数表的地址从虚函数表中获取第二个父接口函数的执行地址,依此类推。
2.根据权利要求1所述的方法,其特征在于,所述根据所述目标C++模块接口的类型和内存结构,在预设存储结构中定义与所述目标C++模块接口具有相同内存结构的对象,包括:
在所述目标C++模块接口的类型为普通接口的情况下,定义一个与所述目标C++模块接口具有相同内存结构的接口对象类型,该类型在实例化后存储所述目标C++模块接口对象实例对应的内存结构中指向虚函数表对象的地址;
在预设存储结构中定义一个与所述目标C++模块接口的虚函数表具有相同内存结构的虚函数表对象类型,该类型在实例化后存储所述目标C++模块接口对象实例的成员函数的实际执行地址。
3.根据权利要求1所述的方法,其特征在于,所述根据所述目标C++模块接口的类型和内存结构,在预设存储结构中定义与所述目标C++模块接口具有相同内存结构的对象,包括:
在所述目标C++模块接口的类型为单继承接口的情况下,定义一个与所述目标C++模块接口具有相同内存结构的接口对象类型,该类型在实例化后存储所述目标C++模块接口对象实例对应的内存结构中指向虚函数表对象的地址;
在预设存储结构中定义一个与所述目标C++模块接口的虚函数表具有相同内存结构的虚函数表对象类型,该类型在实例化后存储所述目标C++模块接口对象实例的成员函数的实际执行地址;单继承接口的父接口按照相同的方法进行定义。
4.根据权利要求1所述的方法,其特征在于,所述根据所述目标C++模块接口的类型和内存结构,在预设存储结构中定义与所述目标C++模块接口具有相同内存结构的对象,包括:
在所述目标C++模块接口的类型为多重继承接口的情况下,定义一个与所述目标C++模块接口具有相同内存结构的接口对象类型,该类型在实例化后存储所述目标C++模块接口对象实例对应的内存结构中指向所有父接口的虚函数表对象的地址,其中,所述目标C++模块接口与第一个继承的父接口共用同一个虚函数表;
在预设存储结构中定义一个与所述目标C++模块接口的虚函数表具有相同内存结构的虚函数表对象类型,该类型在实例化后存储所述目标C++模块接口对象实例的成员函数的实际执行地址;
多重继承接口的所有父接口按照相同的方法进行定义。
5.根据权利要求1所述的方法,其特征在于,所述根据所述目标C++模块接口的类型和内存结构,在预设存储结构中定义与所述目标C++模块接口具有相同内存结构的对象,包括:
在所述目标C++模块接口的类型为单虚继承接口的情况下,定义一个与所述目标C++模块接口具有相同内存结构的接口对象类型,该类型在实例化后存储所述目标C++模块接口对象实例对应的内存结构中指向虚函数表对象的地址、指向虚基址表对象的地址以及指向父接口的虚函数表对象的地址,所述目标C++模块接口的虚函数与父接口的虚函数表不共用;
在预设存储结构中定义一个与所述目标C++模块接口的虚基址表具有相同内存结构的虚基址表对象类型,该类型在实例化后存储所述目标C++模块接口进行接口类型转换的寻址偏移量;
单虚继承接口所继承的父接口使用相同的方式进行定义。
6.根据权利要求1所述的方法,其特征在于,所述根据所述目标C++模块接口的类型和内存结构,在预设存储结构中定义与所述目标C++模块接口具有相同内存结构的对象,包括:
在所述目标C++模块接口的类型为多重虚继承接口的情况下,定义一个与所述目标C++模块接口具有相同内存结构的接口对象类型,该类型在实例化后存储所述目标C++模块接口对象实例对应的内存结构中指向虚函数表对象的地址、指向虚基址表对象的地址以及指向所有父接口的虚函数表对象的地址,所述目标C++模块接口的虚函数表与父接口的虚函数表不共用;
在预设存储结构中定义一个与所述目标C++模块接口的虚基址表具有相同内存结构的虚基址表对象类型,该类型在实例化后存储所述目标C++模块接口进行接口类型转换的寻址偏移量;
多重虚继承接口所继承的父接口使用相同的方式进行定义。
7.根据权利要求1所述的方法,其特征在于,所述根据所述目标C++模块接口的类型,在预设存储结构中定义与所述目标C++模块接口具有相同内存结构的对象,包括:
在所述目标C++模块接口的类型为回调接口的情况下,定义一个与所述目标C++模块接口具有相同内存结构的接口对象类型,该类型在实例化后存储指向虚函数表的地址,由调用者进行实例化,实例化时填充指向虚函数表对象实例的地址;
在预设存储结构中定义与所述目标C++接口的虚函数表具有相同内存结构的虚函数表对象类型,该类型在实例化后存储所述目标C++接口的函数实际指向地址,由调用者进行实例化,实例化时填充实际的执行地址。
8.根据权利要求1所述的方法,其特征在于,预设存储结构为调用者程序运行的内存空间。
9.一种C++模块接口的调用装置,其特征在于,包括:
接口类型确定单元,用于确定目标C++模块接口的类型和内存结构;
对象定义单元,用于根据所述目标C++模块接口的类型和内存结构,在预设存储结构中定义与所述目标C++模块接口具有相同内存结构的对象;
实例转换单元,在预设存储结构中加载所述目标C++模块,获取指向所述目标C++模块接口对象实例的地址,将指向所述目标C++模块接口对象实例的内存地址转换为指向在预设存储结构中定义的与所述目标C++模块接口具有相同内存结构的对象实例的内存地址;
函数调用单元,用于访问转换后的与所述目标C++模块接口具有相同内存结构的对象的数据成员,获取所述目标C++模块接口对象实例的函数的执行地址,通过调用该执行地址,完成对所述目标C++模块接口函数的调用;
其中,所述获取所述目标C++模块接口对象实例的函数的执行地址,包括:
在所述C++模块接口的类型为普通接口的情况下,使用指向虚函数表的地址从虚函数表中获取所述目标C++模块接口对象实例的函数的执行地址;或,
所述获取所述目标C++模块接口对象实例的函数的执行地址,包括:
在所述C++模块接口的类型为单继承接口的情况下,使用指向虚函数表的地址从虚函数表中获取所述目标C++模块接口对象实例的函数和父接口函数的执行地址;或,
所述获取所述目标C++模块接口对象实例的函数的执行地址,包括:
在所述C++模块接口的类型为多重继承接口的情况下,使用指向第一个虚函数表的地址从虚函数表中获取所述目标C++模块接口对象实例的函数和第一个父接口函数的执行地址;
使用指向第二个虚函数表的地址从虚函数表中获取第二个父接口函数的执行地址,依此类推;或,
所述获取所述目标C++模块接口对象实例的函数的执行地址,包括:
在所述C++模块接口的类型为单虚继承接口的情况下,使用指向第一个虚函数表的地址从虚函数表中获取所述目标C++模块接口对象实例的函数的执行地址;
使用指向第二个虚函数表的地址从虚函数表中获取父接口函数的执行地址;或,
所述获取所述目标C++模块接口对象实例的函数的执行地址,包括:
在所述C++模块接口的类型为多重虚继承接口的情况下,使用指向第一个虚函数表的地址从虚函数表中获取所述目标C++模块接口对象实例的函数的执行地址;
使用指向第二个虚函数表的地址从虚函数表中获取第一个父接口函数的执行地址;
使用指向第三个虚函数表的地址从虚函数表中获取第二个父接口函数的执行地址,依此类推。
Priority Applications (1)
Application Number | Priority Date | Filing Date | Title |
---|---|---|---|
CN202011477687.XA CN112559094B (zh) | 2020-12-15 | 2020-12-15 | 一种c++模块接口的调用方法及装置 |
Applications Claiming Priority (1)
Application Number | Priority Date | Filing Date | Title |
---|---|---|---|
CN202011477687.XA CN112559094B (zh) | 2020-12-15 | 2020-12-15 | 一种c++模块接口的调用方法及装置 |
Publications (2)
Publication Number | Publication Date |
---|---|
CN112559094A CN112559094A (zh) | 2021-03-26 |
CN112559094B true CN112559094B (zh) | 2024-04-02 |
Family
ID=75064735
Family Applications (1)
Application Number | Title | Priority Date | Filing Date |
---|---|---|---|
CN202011477687.XA Active CN112559094B (zh) | 2020-12-15 | 2020-12-15 | 一种c++模块接口的调用方法及装置 |
Country Status (1)
Country | Link |
---|---|
CN (1) | CN112559094B (zh) |
Families Citing this family (1)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
CN115952017B (zh) * | 2023-03-09 | 2023-05-23 | 腾讯科技(深圳)有限公司 | 一种内存处理方法、装置、设备及介质 |
Citations (4)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
CN101441566A (zh) * | 2008-11-18 | 2009-05-27 | 腾讯科技(深圳)有限公司 | 一种嵌入式平台和在嵌入式平台上动态链接程序的方法 |
CN104424002A (zh) * | 2013-09-10 | 2015-03-18 | 中国科学院声学研究所 | 一种基于插件机制的动态加载组件方法和系统 |
CN106020932A (zh) * | 2015-05-21 | 2016-10-12 | 中国科学院计算技术研究所 | 一种用于kvm虚拟机系统的安全防护方法及系统 |
CN108804937A (zh) * | 2018-06-12 | 2018-11-13 | 广州华多网络科技有限公司 | 系统函数调用方法及相关装置 |
Family Cites Families (1)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
US20030014555A1 (en) * | 2001-06-29 | 2003-01-16 | Michal Cierniak | System and method for efficient dispatch of interface calls |
-
2020
- 2020-12-15 CN CN202011477687.XA patent/CN112559094B/zh active Active
Patent Citations (4)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
CN101441566A (zh) * | 2008-11-18 | 2009-05-27 | 腾讯科技(深圳)有限公司 | 一种嵌入式平台和在嵌入式平台上动态链接程序的方法 |
CN104424002A (zh) * | 2013-09-10 | 2015-03-18 | 中国科学院声学研究所 | 一种基于插件机制的动态加载组件方法和系统 |
CN106020932A (zh) * | 2015-05-21 | 2016-10-12 | 中国科学院计算技术研究所 | 一种用于kvm虚拟机系统的安全防护方法及系统 |
CN108804937A (zh) * | 2018-06-12 | 2018-11-13 | 广州华多网络科技有限公司 | 系统函数调用方法及相关装置 |
Non-Patent Citations (1)
Title |
---|
C++ Builder调用MATLAB程序的接口方法;杨艳丽等;《福建电脑》;第188-189 * |
Also Published As
Publication number | Publication date |
---|---|
CN112559094A (zh) | 2021-03-26 |
Similar Documents
Publication | Publication Date | Title |
---|---|---|
US5369766A (en) | Object-oriented loader system with support for different load formats | |
US11175896B2 (en) | Handling value types | |
JP3632598B2 (ja) | 変更定数プールを備えたJavaランタイム・システム | |
CA2093451C (en) | Method and mechanism for calling 32-bit functions from 16-bit functions | |
CN108920133B (zh) | 跨语言编程方法、装置、电子设备及存储介质 | |
US6237044B1 (en) | Method for object-oriented programming using dynamic interfaces | |
US6038565A (en) | Object oriented data format mapping mechanism | |
EP0546684A2 (en) | Method stubs for redispatch | |
US20040268301A1 (en) | Adding new compiler methods to an integrated development environment | |
JP2002536742A (ja) | ゼロオーバーヘッドの例外処理 | |
CN112559094B (zh) | 一种c++模块接口的调用方法及装置 | |
WO2024045379A1 (zh) | 编译方法和编译器、Wasm虚拟机 | |
WO2020259163A1 (zh) | 设备部署方法及装置、设备运行方法及电子设备 | |
CN112631684B (zh) | 可执行程序的运行方法、装置、电子设备及计算机存储介质 | |
CN103677778A (zh) | 一种CAP文件Classref常量的解析方法 | |
US7685397B2 (en) | Apparatus and method for managing stacks in virtual machine | |
CN112306539B (zh) | 一种单片机应用层开发方法、系统、终端及介质 | |
CN111008153B (zh) | 一种单元测试方法及系统 | |
Krakowiak et al. | A generic object-oriented virtual machine | |
KR101392046B1 (ko) | 동적 라이브러리를 갖는 인터페이스를 단순화하는 방법, 시스템 및 컴퓨터 판독가능한 저장 매체 | |
WO2022036628A1 (zh) | Gpu着色器程序迭代调用方法、gpu、编译器和gpu驱动器 | |
CN110990018A (zh) | 一种嵌入式系统的编译部署方法、编译方法及编译系统 | |
WO2003036473A1 (en) | Native code isolation in a multi-tasking java virtual machine | |
CN112835654B (zh) | 动态链接库中的函数的调用方法、装置和处理器 | |
US9110793B2 (en) | Inner process |
Legal Events
Date | Code | Title | Description |
---|---|---|---|
PB01 | Publication | ||
PB01 | Publication | ||
SE01 | Entry into force of request for substantive examination | ||
SE01 | Entry into force of request for substantive examination | ||
GR01 | Patent grant | ||
GR01 | Patent grant |