CN114942796B - 插件编译及调用方法、装置、设备及存储介质 - Google Patents
插件编译及调用方法、装置、设备及存储介质 Download PDFInfo
- Publication number
- CN114942796B CN114942796B CN202210482972.3A CN202210482972A CN114942796B CN 114942796 B CN114942796 B CN 114942796B CN 202210482972 A CN202210482972 A CN 202210482972A CN 114942796 B CN114942796 B CN 114942796B
- Authority
- CN
- China
- Prior art keywords
- plug
- function
- target
- variable
- host program
- 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 63
- 230000006870 function Effects 0.000 claims abstract description 428
- 238000013507 mapping Methods 0.000 claims abstract description 50
- 238000012545 processing Methods 0.000 claims description 10
- 238000009877 rendering Methods 0.000 claims description 7
- 238000012544 monitoring process Methods 0.000 claims description 6
- 238000011161 development Methods 0.000 abstract description 20
- 230000004927 fusion Effects 0.000 abstract description 9
- 230000007246 mechanism Effects 0.000 abstract description 9
- 230000008859 change Effects 0.000 abstract description 4
- 238000012217 deletion Methods 0.000 abstract 1
- 230000037430 deletion Effects 0.000 abstract 1
- 238000004891 communication Methods 0.000 description 9
- 238000010586 diagram Methods 0.000 description 6
- 238000004590 computer program Methods 0.000 description 4
- 238000012423 maintenance Methods 0.000 description 4
- 230000006978 adaptation Effects 0.000 description 2
- 230000003190 augmentative effect Effects 0.000 description 2
- 230000009286 beneficial effect Effects 0.000 description 2
- 238000010276 construction Methods 0.000 description 2
- 238000005516 engineering process Methods 0.000 description 2
- 230000003993 interaction Effects 0.000 description 2
- 230000003287 optical effect Effects 0.000 description 2
- 230000008569 process Effects 0.000 description 2
- 230000003068 static effect Effects 0.000 description 2
- 230000001413 cellular effect Effects 0.000 description 1
- 239000013078 crystal Substances 0.000 description 1
- 230000001419 dependent effect Effects 0.000 description 1
- 238000013461 design Methods 0.000 description 1
- 239000004973 liquid crystal related substance Substances 0.000 description 1
- 238000012986 modification Methods 0.000 description 1
- 230000004048 modification Effects 0.000 description 1
- 230000037361 pathway Effects 0.000 description 1
- 230000004044 response Effects 0.000 description 1
- 238000012360 testing method Methods 0.000 description 1
- 238000012546 transfer Methods 0.000 description 1
- 230000001960 triggered effect Effects 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/445—Program loading or initiating
- G06F9/44521—Dynamic linking or loading; Link editing at or after load time, e.g. Java class loading
- G06F9/44526—Plug-ins; Add-ons
-
- G—PHYSICS
- G06—COMPUTING; CALCULATING OR COUNTING
- G06F—ELECTRIC DIGITAL DATA PROCESSING
- G06F8/00—Arrangements for software engineering
- G06F8/40—Transformation of program code
- G06F8/41—Compilation
-
- 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/4488—Object-oriented
- G06F9/449—Object-oriented method invocation or resolution
Landscapes
- Engineering & Computer Science (AREA)
- Software Systems (AREA)
- Theoretical Computer Science (AREA)
- General Engineering & Computer Science (AREA)
- Physics & Mathematics (AREA)
- General Physics & Mathematics (AREA)
- Stored Programmes (AREA)
Abstract
本公开关于一种插件编译及调用方法、装置、设备及存储介质,宿主程序接收到插件调用请求后,首先确定与目标插件标识对应的目标插件对象与目标插件对象对应的插件子类;再访问插件子类内部的函数映射,以确定与目标索引标识对应的目标函数,最后调用目标插件对象中的目标函数。宿主程序与插件通过这种调用机制,可以实现插件内部的各种功能,同时业务插件有新增或删减函数时,只需发布编译好的动态库文件,宿主程序自动热加载,宿主程序无需任何变动,实现框架与业务逻辑的解耦。本公开技术方案实现了在开发阶段插件与宿主程序解耦,部署阶段插件功能与宿主程序的功能融合。
Description
技术领域
本公开涉及计算机技术领域,尤其涉及一种插件编译及调用方法、装置、设备及存储介质。
背景技术
插件是一种遵循一定规范的应用程序接口编写出来的程序,用于实现特定的业务功能。通过编译器对插件代码进行编译,可生成动态链接库文件。宿主程序启动运行时,加载动态链接库文件,进而可以调用插件内定义的函数。
在实际应用中,不同的业务功能通常需要相同的基础能力支撑,如果针对每个业务功能都做独立的软件开发,在基础能力部分便会存在重复建设,将会极大地降低开发、维护效率。因此,如何提高插件的开发和维护效率,是亟待解决的技术问题。
发明内容
本公开提供一种插件编译及调用方法、装置、设备及存储介质,可以实现插件的开发阶段解耦、部署阶段功能融合,从而提高插件的开发和维护效率。本公开的技术方案如下:
根据本公开实施例的第一方面,提供一种插件调用方法,包括:接收插件调用请求,所述插件调用请求包括目标插件标识和目标索引标识;根据所述目标插件标识,确定目标插件对象以及预先定义在宿主程序中的与所述目标插件对象相对应的插件子类,所述目标插件对象中的函数具有索引标识,所述插件子类包括函数映射,所述函数映射包括所述目标插件对象中的每个函数的索引标识到对应函数的映射;从所述插件子类的所述函数映射中,确定与所述目标索引标识对应的目标函数;对所述目标插件对象中的所述目标函数进行调用。
结合第一方面,在第一方面可能的实现方式中,所述接收插件调用请求之前,还包括:加载动态库文件,所述动态库文件与所述目标插件对象对应,所述动态库文件包括导出函数和插件代码块,所述导出函数包括所述插件代码块内的每个函数和每个函数的所述索引标识;调用所述导出函数,以通过所述导出函数,根据所述插件代码块生成所述目标插件对象,并获取所述目标插件对象的指针,以及根据所述插件代码块内的每个函数和每个函数的所述索引标识,对所述目标插件对象对应的插件子类中的函数映射进行赋值。
结合第一方面,在第一方面可能的实现方式中,所述调用所述导出函数之后,所述方法还包括:建立所述目标插件对象的指针与所述目标插件标识之间的对应关系。
结合第一方面,在第一方面可能的实现方式中,所述加载动态库文件,包括:监听指定路径下的文件信息;当监听到新增的动态库文件时,加载所述新增的动态库文件。
结合第一方面,在第一方面可能的实现方式中,所述根据所述目标插件标识,确定目标插件对象以及预先定义在宿主程序中的与所述目标插件对象相对应的插件子类,包括:根据预先建立的插件对象的指针与插件标识之间的对应关系,确定与所述目标插件标识对应的指针,所述目标插件标识对应的指针所指向的插件对象为所述目标插件对象;根据所述目标插件对象的类型,将所述目标插件标识对应的指针转换成对应插件子类的指针,所述对应插件子类的指针所指向的插件子类为所述目标插件对象对应的插件子类。
结合第一方面,在第一方面可能的实现方式中,所述宿主程序具有第一变量空间,所述第一变量空间包括所述宿主程序的每个插件对象的变量;所述方法还包括:通过所述第一变量空间预设的变量操作接口,响应第一插件对象根据第一插件对象标识或者第二插件对象标识对所述第一变量空间中对应插件对象的变量执行的操作,所述第一插件对象为所述宿主程序的任意插件对象,所述第二插件对象为除所述第一插件对象以外的任意插件对象,所述操作包括获取变量的操作、设置变量的操作以及删除变量的操作。
结合第一方面,在第一方面可能的实现方式中,所述宿主程序具有第二变量空间,所述第二变量空间中包括所述宿主程序对所述宿主程序的每个插件对象开放的宿主函数;所述方法还包括:通过所述第二变量空间预设的函数调用接口,响应任意插件对象根据目标宿主函数的函数标识对所述第二变量空间中的目标宿主函数的调用。
结合第一方面,在第一方面可能的实现方式中,所述第二变量空间中还包括所述宿主程序对每个所述插件对象开放的宿主变量,所述方法还包括:通过所述第二变量空间预设的变量操作接口,响应任意插件对象对所述第二变量空间中任意变量的操作,所述操作包括获取变量的操作和设置变量的操作。
结合第一方面,在第一方面可能的实现方式中,所述宿主程序定义有插件基类,所述插件基类中定义有至少一种类型的插件对象公共的函数和属性,每种类型的插件对象所对应的插件子类继承所述插件基类。
结合第一方面,在第一方面可能的实现方式中,所述目标插件对象中的每个函数的索引标识为所述目标插件对象对应的插件子类中声明的函数标识。
根据本公开实施例的第二方面,提供一种插件编译方法,所述方法包括:获取与待编译的插件代码块对应的配置信息,所述配置信息包括所述插件代码块内定义的每个函数和每个函数的索引标识;根据所述每个函数和每个函数的索引标识,生成导出函数代码块,所述导出函数用于根据所述插件代码块生成插件对象,并返回所述插件对象的指针给宿主程序,以及根据所述每个函数和每个函数的索引标识对预先定义在所述宿主程序中的与所述插件对象对应的插件子类中的函数映射进行赋值;对所述导出函数代码块和所述插件代码块进行编译,得到动态库文件,并将所述动态库文件发布到所述宿主程序的指定路径下。
结合第二方面,在第二方面可能的实现方式中,所述根据待编译的插件代码块内定义的每个函数和每个函数的索引标识,生成导出函数代码块,包括:获取模板代码块,所述模板代码块用于实现所述导出函数;将所述每个函数和每个函数的索引标识渲染到所述模板代码块中,得到所述导出函数代码块。
根据本公开实施例的第三方面,提供一种插件调用装置,包括:请求接收模块,用于接收插件调用请求,所述插件调用请求包括目标插件标识和目标索引标识;插件对象确定模块,用于根据所述目标插件标识,确定目标插件对象以及预先定义在宿主程序中的与所述目标插件对象相对应的插件子类,所述目标插件对象中的函数具有索引标识,所述插件子类包括函数映射,所述函数映射包括所述目标插件对象中的每个函数的索引标识到对应函数的映射;函数确定模块,用于从所述插件子类的所述函数映射中,确定与所述目标索引标识对应的目标函数;函数调用模块,用于对所述目标插件对象中的所述目标函数进行调用。
结合第三方面,在第三方面可能的实现方式中,还包括:加载模块,用于加载动态库文件,所述动态库文件与所述目标插件对象对应,所述动态库文件包括导出函数和插件代码块,所述导出函数包括所述插件代码块内的每个函数和每个函数的所述索引标识;导出模块,用于调用所述导出函数,以通过所述导出函数,根据所述插件代码块生成所述目标插件对象,并获取所述目标插件对象的指针,以及根据所述插件代码块内的每个函数和每个函数的所述索引标识,对所述目标插件对象对应的插件子类中的函数映射进行赋值。
结合第三方面,在第三方面可能的实现方式中,所述装置还包括:对应关系建立模块,用于建立所述目标插件对象的指针与所述目标插件标识之间的对应关系。
结合第三方面,在第三方面可能的实现方式中,所述加载模块,具体用于:监听指定路径下的文件信息;当监听到新增的动态库文件时,加载所述新增的动态库文件。
结合第三方面,在第三方面可能的实现方式中,所述插件对象确定模块,具体用于:根据预先建立的插件对象的指针与插件标识之间的对应关系,确定与所述目标插件标识对应的指针,所述目标插件标识对应的指针所指向的插件对象为所述目标插件对象;根据所述目标插件对象的类型,将所述目标插件标识对应的指针转换成对应插件子类的指针,所述对应插件子类的指针所指向的插件子类为所述目标插件对象对应的插件子类。
结合第三方面,在第三方面可能的实现方式中,所述装置还包括:所述宿主程序具有第一变量空间,所述第一变量空间包括所述宿主程序的每个插件对象的变量;所述装置还包括:第一操作模块,用于通过所述第一变量空间预设的变量操作接口,响应第一插件对象根据第一插件对象标识或者第二插件对象标识对所述第一变量空间中对应插件对象的变量执行的操作,所述第一插件对象为所述宿主程序的任意插件对象,所述第二插件对象为除所述第一插件对象以外的任意插件对象,所述操作包括获取变量的操作、设置变量的操作以及删除变量的操作。
结合第三方面,在第三方面可能的实现方式中,所述宿主程序具有第二变量空间,所述第二变量空间中包括所述宿主程序对所述宿主程序的每个插件对象开放的宿主函数;所述装置还包括:第二操作模块,用于通过所述第二变量空间预设的函数调用接口,响应任意插件对象根据目标宿主函数的函数标识对所述第二变量空间中的目标宿主函数的调用。
结合第三方面,在第三方面可能的实现方式中,所述第二变量空间中还包括所述宿主程序对每个所述插件对象开放的宿主变量,所述第二操作模块,还用于:通过所述第二变量空间预设的变量操作接口,响应任意插件对象对所述第二变量空间中任意变量的操作,所述操作包括获取变量的操作和设置变量的操作。
结合第三方面,在第三方面可能的实现方式中,所述宿主程序定义有插件基类,所述插件基类中定义有至少一种类型的插件对象公共的函数和属性,每种类型的插件对象所对应的插件子类继承所述插件基类。
结合第三方面,在第三方面可能的实现方式中,所述目标插件对象中的每个函数的索引标识为所述目标插件对象对应的插件子类中声明的函数标识。
根据本公开实施例的第四方面,提供一种插件编译装置,所述装置包括:配置信息获取模块,用于获取与待编译的插件代码块对应的配置信息,所述配置信息包括所述插件代码块内定义的每个函数和每个函数的索引标识;函数生成模块,用于根据所述每个函数和每个函数的索引标识,生成导出函数代码块,所述导出函数用于根据所述插件代码块生成插件对象,并返回所述插件对象的指针给宿主程序,以及根据所述每个函数和每个函数的索引标识对预先定义在所述宿主程序中的与所述插件对象相对应的插件子类中的函数映射进行赋值;编译模块,用于对所述导出函数代码块和所述插件代码块进行编译,得到动态库文件,并将所述动态库文件发布到所述宿主程序的指定路径下。
结合第四方面,在第四方面可能的实现方式中,所述函数生成模块,具体用于:获取模板代码块,所述模板代码块用于实现所述导出函数;将每个函数和每个函数的索引标识渲染到所述模板代码块中,得到所述导出函数代码块。
根据本公开实施例的第五方面,提供一种电子设备,包括:处理器和用于存储所述处理器可执行指令的存储器;其中,所述处理器被配置为执行所述可执行指令,以实现第一方面或者第二方面中任一项所述的方法。
根据本公开实施例的第六方面,提供一种计算机可读存储介质,当所述计算机可读存储介质中的指令由装置执行时,使得装置能够执行第一方面或者第二方面中任一项所述的方法;当所述计算机可读存储介质中的指令由电子设备的处理器执行时,使得电子设备的处理器能够执行第一方面或者第二方面中任一项所述的方法。
根据本公开实施例的第七方面,提供一种计算机程序产品,包括计算机程序或指令,所述计算机程序或指令被处理器执行时实现第一方面或者第二方面中任一项所述的方法。
本公开的实施例提供的技术方案至少带来以下有益效果:
在开发阶段,预先在宿主程序中定义插件基类和每种类型插件对应的插件子类,基类中包含各类型插件所必须的方法和属性,子类继承该基类并根据具体的业务场景定义业务函数的函数原型。插件子类中还包括函数映射。
在编译阶段,首先提供一个供编译器读取的配置文件,配置文件中除了包括插件的基础描述信息外,关键还包括插件内定义的每个函数及其索引标识(是指插件子类中声明的函数标识)。编译器首先根据该配置文件生成导出函数代码,并生成包含该导出函数代码和插件代码的动态库文件,添加到宿主程序中。
在插件加载阶段,宿主程序在加载完该动态库文件后,会通过前述导出函数,生成插件对象并返回插件对象的指针给到宿主程序,宿主程序则会建立插件指针与插件标识之间的对应关系。同时,导出函数还会对插件子类内部的函数映射进行赋值,使得函数映射中包括插件的每个函数的索引标识到对应函数的映射。
在插件调用阶段,可以根据目标插件标识和目标索引标识,请求调用目标插件对象内定义的目标函数。宿主程序接收到插件调用请求后,首先确定与目标插件标识对应的目标插件对象和目标插件对象相对应的插件子类;再访问插件子类内部的函数映射,以确定与目标索引标识对应的目标函数,最后对目标插件对象中的目标函数进行调用。
宿主程序与插件通过这种调用机制,可以实现插件内的各种业务功能,同时业务插件有新增或删减函数时,只需发布编译好的动态库文件,宿主程序自动热加载,宿主程序无需任何变动,实现框架与业务逻辑的解耦。本公开技术方案实现了在开发阶段插件与宿主程序解耦,部署阶段插件功能与宿主程序的功能融合。
应当理解的是,以上的一般描述和后文的细节描述仅是示例性和解释性的,并不能限制本公开。
附图说明
此处的附图被并入说明书中并构成本说明书的一部分,示出了符合本公开的实施例,并与说明书一起用于解释本公开的原理,并不构成对本公开的不当限定。
图1是根据一示例性实施例示出一种插件实现机制示意图;
图2是根据一示例性实施例示出的一种插件编译方法流程图;
图3是根据一示例性实施例示出的一种插件调用方法流程图;
图4是根据一示例性实施例示出的一种插件编译装置示意图;
图5是根据一示例性实施例示出的一种插件调用装置示意图;
图6是根据一示例性实施例示出的一种电子设备的结构示意图。
具体实施方式
为了使本领域普通人员更好地理解本公开的技术方案,下面将结合附图,对本公开实施例中的技术方案进行清楚、完整地描述。
需要说明的是,本公开的说明书和权利要求书及上述附图中的术语“第一”、“第二”等是用于区别类似的对象,而不必用于描述特定的顺序或先后次序。应该理解这样使用的数据在适当情况下可以互换,以便这里描述的本公开的实施例能够以除了在这里图示或描述的那些以外的顺序实施。以下示例性实施例中所描述的实施方式并不代表与本公开相一致的所有实施方式。相反,它们仅是与如所附权利要求书中所详述的、本公开的一些方面相一致的装置和方法的例子。
另外,在本公开实施例的描述中,除非另有说明,“/”表示或的意思,例如,A/B可以表示A或B。本文中的“和/或”仅仅是一种描述关联对象的关联关系,表示可以存在三种关系,例如,A和/或B,可以表示:单独存在A,同时存在A和B,单独存在B这三种情况。另外,在本公开实施例的描述中,“多个”是指两个或两个以上。
在介绍本公开实施例之前,对本公开实施例涉及的术语解释如下:
插件(plug-in):使用golang语言开发的一个软件程序包,可以实现实际业务功能,通过编译器编译,生成动态链接库.so文件。宿主程序在运行时加载动态链接库.so文件,进而可以在宿主程序内调用plug-in内定义的函数。
宿主程序:具有完整功能的、独立运行的程序。在运行时可以加载plug-in的动态链接库.so文件,进而调用plug-in内定义的函数。
插件类型(Kind):代表plug-in的类型,plug-in可以按功能划分多种类型,每种类型用一个Kind来表示。例如,数据服务插件和作业类型插件。其中,数据服务插件内部定义一个或多个函数,通过调用这些函数对外提供服务,以实现MVCWeb服务器的M和C的功能。作业插件内部定义一个或多个作业函数,宿主程序加载该类型的插件后,依次触发每一个作业函数,让每一个作业函数执行起来。
热加载:在不重启宿主程序的情况下,将plug-in的新功能加载到宿主程序内部,使得宿主程序具备新功能。
如在背景技术中所述,不同的业务功能通常需要相同的基础能力支撑,如果针对每个业务功能都做独立的软件开发,在基础能力部分便会存在重复建设,将会极大地降低开发、维护效率。因此,如何将不同业务功能都需要的基础能力独立到插件平台上,再基于每个业务功能的特定需求开发插件,实现在开发阶段解耦、部署阶段功能融合,是亟待解决的技术问题。
Tidb数据库中有一套基于golang原生插件包(plug-in)的插件实现方案。在其方案中,宿主程序内部事先声明插件的结构原型(struct原型,类似java中的接口类),里面定义了该类插件所必须的函数原型。在开发业务插件时,需继承对应的结构原型,以实现接口所声明的所有函数。插件开发完成后,需提供一份配置文件(manifest.toml)来描述插件的关键信息,如插件名、插件类型,插件版本等,最为关键的是,在manifest.toml配置文件中通过指定配置项(export配置项),将插件接口中声明的函数与业务插件中的具体函数实现进行一对一的关联。最后使用特定的编译工具来编译业务插件,生成.so动态链接库(.so文件)。
然而,上述实现方案有如下缺陷:
首先,在其定义插件类型时,每种类型的插件所包含的函数数量、函数声明(包括函数名)是固定的。开发者在实现具体业务插件时只能导出固定数量的函数,若需要导出更多数量的函数,则需要修改插件原型定义,并对宿主程序进行编译发布。同时,固定的函数名,表示宿主程序只能通过硬编码的形式去调用插件的函数,无法真正实现解耦。
其次,插件***为业务插件提供的***变量空间,使得业务插件可以在***变量空间中注册和更新变量,但要求所有的变量名必须全局唯一。在多插件的场景下,容易出现变量冲突。为避免变量冲突,一般需要给变量名增加插件的名称作为前缀,这在一定程度上影响了变量的可读性;同时没有一个统一的途径来对插件暴露宿主程序的一些内部功能,这让插件不能很好的利用宿主程序已有的一些功能。
最后,应用场景比较单一,扩展性较差,无法满足实际业务不同场景下的需求。比如开发Web服务时,要求可暴露不限数量的函数及任意的函数名;再如某些作业场景,需要插件一旦加载成功后便触发指定函数进行常驻执行。
基于此,本公开实施例提供一种灵活、可扩展的插件实现机制,即一种插件编译方法和插件调用方法,该方法可以应用于电子设备,如终端设备或者服务器。终端设备可以是手机、平板电脑、桌面型、膝上型、手持计算机、笔记本电脑、超级移动个人计算机(ultra-mobile personal computer,UMPC)、上网本,以及蜂窝电话、个人数字助理(personaldigital assistant,PDA)、增强现实(augmented reality,AR)\虚拟现实(virtualreality,VR)设备等可以安装并使用应用程序的设备,本公开对该终端的具体形态不作特殊限制。其可以与用户通过键盘、触摸板、触摸屏、遥控器、语音交互或手写设备等一种或多种方式进行人机交互。
图1为本公开实施例提供的一种插件实现机制的实现过程示意图,如图1所示:
在开发阶段,宿主程序在内部为所有插件定义了插件基类,同时预先定义满足特定业务场景的插件子类。
本公开示例性示出的一种插件基类内容如下:
可以看出,插件基类中包含各类型插件所必须的方法和属性,如类型、名称、版本号、依赖的插件名及其版本、描述信息和生命周期函数。
本公开实例性示出的一种插件子类内容如下:
可以看出,插件子类继承了插件基类,同时定义了满足特定业务场景需求的函数原型,插件子类内部通过哈希映射(hashMap)持有不定个数的函数映射。基于具体业务场景开发插件时,只需按照对应插件子类定义的函数原型实现业务功能函数。应理解,当有新的业务场景需求而现有插件类型不能满足时,可以按照这个思路定义新的插件子类。
在编译阶段,首先提供一个供编译器读取的配置文件,配置文件中除了包括插件的基础描述信息外,关键还包括export配置项,其中记载插件子类内定义的每个函数的索引标识,索引标识为插件对外声明的函数标识,即对应插件子类中hashMap的索引(key)值。以某个函数的索引标识作为索引值,可在插件子类内部的hashMap中查找到该实际函数。编译时,编译器首先根据该配置文件生成导出函数代码,并保存到一个临时golang代码文件中,再将这个代码文件连同业务插件代码一起进行编译,生成动态库文件,最后将动态库文件发布到宿主程序指定的目录下。
在插件加载阶段,宿主程序通过plug-in包加载该动态库文件。在加载完动态库文件后,在动态库内通过函数名查找前述的导出函数,通过执行导出函数,获得该插件实例化后的指针。宿主程序内部建立该插件标识与插件对象指针的对应关系。可选的,宿主程序在获得插件对象指针后,可以根据具体插件类型需要,做一些特殊处理。例如,宿主程序在加载完作业类型插件并获得插件对象指针后,便可以遍历插件内部的函数映射并触发函数执行。
基于上述开发阶段和编译阶段以及插件加载阶段的实现,插件对象内部保存有哈希映射,哈希映射中包括插件的每个函数的索引标识到实际函数的映射。
在插件调用阶段,可以根据目标插件标识和目标索引标识,请求调用目标插件对象内定义的目标函数。例如,宿主程序接收到插件调用请求后,首先确定与目标插件标识对应的目标插件对象的指针,通过判断目标插件对象的类型,将目标插件对象的指针转换为对应插件子类的指针,再通过插件子类的指针,访问插件子类内部的哈希映射,以确定与目标索引标识对应的目标函数,最后对目标插件对象中的目标函数进行调用。
由图1示出的插件实现机制的实现过程可以看出,本公开技术方案实现了在开发阶段插件与宿主程序解耦,部署阶段插件功能与宿主程序的功能融合。
图2为本公开实施例提供一种插件编译方法流程图,如图2所示,该方法可以包括如下步骤:
S201,获取与待编译的插件代码块对应的配置信息,该配置信息包括插件代码块内定义的每个函数和每个函数的索引标识。
在可能的实现方式中,上述配置信息可以是manifest.toml配置文件。
本公开示例性示出的一种配置文件内容如下:
kind="Service"
name="serviceHandLe"
version=1
description="just a test"
validate="Validate"
onInit="OnInit"
onShutdown="OnShutdown"
requirements=[
]
export=[
{name="aaa",impl="DoService"},
{name="bbb",impl="GetAgentList"},
{name="ccc",impl="ExecTask"}
]
可以看出,该配置文件中描述plugin的一些基础信息,如插件类型、插件名称、插件的版本、插件的描述信息,还包括export配置项,该项具体是一个json数组,每个json{name=“”,impl=“”}中声明一个需要导出的函数,name为该函数的索引标识,impl为该函数。
S202,根据配置信息,生成导出函数代码块。
上述导出函数用于创建某种具体插件类型的插件对象,并对插件对象内的变量进行赋值,包括对插件基类所声明的成员变量和生命周期函数进行赋值。特别的,通过配置信息中包括的每个函数和每个函数的索引标识对插件子类中的函数映射进行赋值。
其中,上述函数映射可以是函数的索引标识到实际函数的映射。
在可能的实现方式中,S202具体包括:获取模板代码块,模板代码块用于实现上述导出函数;将插件的基础信息、每个函数和每个函数的索引标识渲染到模板代码块中,得到导出函数代码块。通过将函数及其索引标识渲染到模板代码块中,使得导出函数可以将每个函数及其索引标识赋值到插件子类内部的函数映射中。
本公开实施例提供的一种模板代码文本如下:
更为具体的实现方式中,模板代码块定义在编码器内部。编译器首先读取上述配置信息,然后将读取到的内容渲染进模板代码当中,最后将渲染后的代码写入到一个临时go文件中。该临时go文件会随插件代码块共同生成动态链接库文件。
在可能的实现方式中,上述导出函数还用于获取插件对象对应的指针,并返回给宿主程序。宿主程序可以通过该导出函数返回的指针,获得插件对象的指针,进而预先建立插件对象的指针与插件对象标识之间的对应关系,这样,在已知插件对象标识的情况下,即可根据该对应关系查找到插件对象的指针,进而可以根据插件对象的指针访问插件对象内部的数据,实现对其内部函数的调用。
应理解,导出函数用于创建和初始化插件对象并返回插件对象的指针,当有特殊的业务场景需要全新的插件类型,且新类型的插件在对象创建和初始化有特殊要求时,可以为新类型插件准备新的导出函数模板代码。如此,使整个插件***具备扩展性。
S203,对导出函数代码块和业务插件代码块进行编译,以生成动态库文件,并将所述动态库文件发布到宿主程序的指定路径下。
由上述S201-S203可以看出,在编译阶段,首先提供一个供编译器读取的配置文件,配置文件中除了包括插件的基础描述信息外,关键还包括插件内定义的每个函数及其索引标识。编译器首先根据该配置文件生成导出函数代码,并编译生成包含该导出函数代码和具体业务插件代码的动态库文件,发布到宿主程序中。基于此,在插件加载阶段,宿主程序在加载完该动态库文件后,会通过前述导出函数,生成插件对象指针,并在内部维护插件对象标识与插件对象指针的对应关系。基于此,在插件加载阶段,宿主程序在加载完该动态库文件后,会通过前述导出函数,生成插件对象并返回插件对象的指针给到宿主程序,宿主程序则会建立插件指针与插件标识之间的对应关系。同时,导出函数还会对对应插件子类内部的函数映射进行赋值,使得函数映射中包括插件的每个函数的索引标识到实际函数的映射。这样,才能保证在调用阶段,调用方可以使用目标插件标识和目标索引标识向宿主程序请求调用对应的函数,此时,宿主程序首先确定与目标插件标识对应的目标插件对象和目标插件对象相对应的插件子类;再访问插件子类内部的函数映射,以确定与目标索引标识对应的目标函数,最后对目标插件对象中的目标函数进行调用。
宿主程序与插件通过这种调用机制,可以实现插件内的各种业务功能,同时业务插件有新增或删减函数时,只需发布编译好的动态库文件,宿主程序自动热加载,宿主程序无需任何变动,实现框架与业务逻辑的解耦。本公开技术方案实现了在开发阶段插件与宿主程序解耦,部署阶段插件功能与宿主程序的功能融合。
图3为本公开实施例提供一种插件调用方法流程图,如图3所示,该方法可以包括如下步骤:
S301,接收插件调用请求,所述插件调用请求包括目标插件标识和目标索引标识。
S301中,目标插件标识为目标插件对象的插件标识,即插件名称。目标插件对象为该插件调用请求所请求调用的插件对象。目标索引标识为目标函数的索引标识,目标函数为目标插件对象内部定义的函数。
本公开实施例中,宿主程序内部定义了所有插件的基类,同时预先定义了对应于各种插件类型的插件子类,插件基类包含所有插件对象共同具备的属性和生命周期函数,具体类型的插件子类继承插件基类,并基于自身所支撑的业务场景需求,定义特定的函数原型及函数映射。示例性的,宿主程序内定义的插件基类和插件子类可如上述实施例所示。将插件基类和各类型插件的插件子类预先定义在宿主程序中,基于具体业务场景开发插件时,只需按照对应的插件子类所声明的函数原型开发业务函数,通过配置文件将插件代码编译成对应插件子类的动态库,宿主程序加载后便能以该插件子类的实例化对象进行调用。实现在开发阶段解耦、部署阶段功能融合。
S302,确定所述目标插件标识对应的目标插件对象,及预先定义在宿主程序中的与目标插件对象相对应的插件子类,插件子类包括函数映射,函数映射包括目标插件对象中的每个函数的索引标识到对应函数的映射。
本公开实施例中,在S301之前,还包括:加载动态库文件,动态库文件与目标插件对象对应,动态库文件包括导出函数和插件代码块;调用导出函数,导出函数用于创建和初始化插件对象,并返回插件对象的指针。具体的,上述导出函数首先创建并初始化插件对象,根据插件的配置文件对插件对象的属性进行赋值,其中配置文件中定义的函数及其索引标识也会逐一赋值到插件对象的函数映射中。这样,宿主程序确定与目标插件标识对应的目标插件对象及对应的插件子类后,通过访问插件子类内部的函数映射,即可确定与目标索引标识对应的目标函数,进而调用目标函数。
本公开实施例中,宿主程序监听指定路径下的文件信息;当监听到新增的动态库文件时,加载该动态库文件。将与插件对应的动态库文件统一保存在宿主程序的指定路径下,宿主程序监听指定路径下的文件信息,当监听到新增的动态库文件时,即加载该新增的动态库文件,实现对动态库文件的热加载。
在上述实现方式中,宿主程序还可以通过导出函数获取目标插件对象的指针。宿主程序可以根据目标插件对象的指针,建立所述目标插件对象的指针与所述目标插件标识之间的对应关系。通过预先建立插件对象的指针与插件对象标识之间的对应关系,在已知插件对象标识的情况下,即可根据该对应关系查找到插件对象的指针,进而可以根据插件对象的指针访问插件对象内部的数据,实现对其内部函数的调用。
具体的,可以根据预先建立的插件对象的指针与插件标识之间的对应关系,确定与目标插件标识对应的指针,目标插件标识对应的指针所指向的插件对象为目标插件对象。再根据目标插件对象的类型,将目标插件标识对应的指针转换成对应插件子类的指针,对应插件子类的指针所指向的插件子类为目标插件对象对应的插件子类。预先建立插件对象的指针与插件对象标识之间的对应关系,这样,在已知插件对象标识的情况下,即可根据该对应关系查找到插件对象的指针,进而可以根据插件对象的指针访问插件对象内部的数据,实现对其内部函数的调用。以及,根据插件对象的指针,转换得到对应插件子类的指针,进而可以根据插件子类的指针,访问插件子类的函数映射,以当给定函数的索引标识时,可以确定对应的函数。
S303,从所述插件子类中的所述函数映射中,确定与所述目标索引标识对应的目标函数。
S304,对所述目标插件对象中的所述目标函数进行调用。
基于上述开发阶段和编译阶段以及插件加载阶段的实现,插件对象对应的插件子类内部保存有函数映射,函数映射中包括插件的每个函数的索引标识到对应函数的映射。可以根据目标插件标识和目标索引标识,请求调用目标插件对象内定义的目标函数。宿主程序接收到插件调用请求后,首先确定与目标插件标识对应的目标插件对象;然后根据插件对象的类型,将插件对象指针转为对应插件子类的指针,再访问插件子类内部的函数映射,以确定与目标索引标识对应的目标函数,最后调用目标函数。由于在插件子类内部保存有上述函数映射,在开发阶段,可以在插件内定义任意数量和名称的函数,而不受宿主程序内所定义的函数数量的限制。调用具体函数时,根据目标函数的索引标识即可在函数映射中查找到该目标函数。本公开技术方案实现了在开发阶段插件与宿主程序解耦,部署阶段插件功能与宿主程序的功能融合。
在一些实施例中,在宿主程序内部设置第一变量空间,用于保存所有插件对象有关的变量,每个插件对象的变量与插件标识绑定,从而摆脱相关技术中要求所有的变量名必须全局唯一的限制,避免不同插件之间因变量名相同而无法注册变量。同时,向所有插件对象提供变量操作接口。基于此,本公开实施例提供的插件调用方法还包括:通过第一变量空间预设的变量操作接口,响应第一插件对象根据指定插件对象标识对第一变量空间中与指定插件对象标识关联的变量执行的操作,第一变量空间中包括每个插件对象的变量,插件对象的变量与插件对象的标识相关联,操作包括获取变量的操作、设置变量的操作以及删除变量的操作。例如,通过第一变量空间预设的变量操作接口,响应第一插件对象根据第一插件对象标识对第一变量空间中的第一插件对象的变量执行的操作,该第一插件对象可以为宿主程序的任意插件对象。再如,通过第一变量空间预设的变量操作接口,响应第一插件对象根据第二插件对象标识对第一变量空间中的第二插件对象的变量执行的操作,第二插件对象可以为宿主程序的除第一插件对象以外的任意插件对象。
通过在宿主程序内部设置第一变量空间,一方面,使得插件对象可以基于该变量操作接口和自身的插件标识,对第一变量空间中自身的变量进行操作,如设置、获取或者删除;另一方面,还能使得插件对象可以基于该变量操作接口和其他插件的标识,对第一变量空间中其他插件的变量进行访问,实现插件之间的数据通信。
在一些实施例中,在宿主程序内部设置第二变量空间,用于保存宿主程序对所有插件对象开放的函数(即宿主函数),并对插件对象提供函数调用接口,使得插件对象可以基于该函数调用接口和目标宿主函数的函数标识,对第二变量空间中的目标宿主函数进行调用,使得插件可以复用宿主程序的功能。也就是说,本公开实施例提供的插件调用方法还包括:通过第二变量空间预设的函数调用接口,响应任意插件对象根据目标宿主函数的函数标识对第二变量空间中的目标宿主函数的调用,第二变量空间中包括宿主程序对插件对象开放的宿主函数。
结合上述实施例,在另一些实施例中,第二变量空间中还包括所述宿主程序对所述目标插件对象开放的宿主变量。本公开实施例提供的插件调用方法还包括:通过第二变量空间预设的变量操作接口,接收目标插件对象对第二变量空间中任意变量的操作,操作包括获取变量的操作和设置变量的操作。通过第二变量空间中保存宿主程序对插件对象开放的变量(即宿主变量),并对插件对象提供变量操作接口,使得插件对象可以基于该变量操作接口对第二变量空间中任意宿主变量的获取操作、设置操作,实现插件与宿主程序之间的数据通信。
需要说明的是,上述可以对第一变量空间中的变量及第二变量控件中的变量和函数进行操作的插件对象可以是任意一个插件对象。
由本公开实施例可以看出,本公开技术方案可以构建出一种具有热加载能力、业务与框架高度解耦、具备web服务器功能的插件***,同时也为其他特殊业务场景提供了插件***的实现思路。将插件导出的函数使用函数映射进行保存和索引,打破tidb插件对函数个数和签名的硬限制;提供不同插件之间、插件与宿主程序之间的数据与功能通讯渠道,实现功能复用的目的;通过插件调用方式的设计,使得插件***具备web服务器的基本功能;同时可以按需扩展插件类型(如作业类型插件等等),覆盖更多业务场景,增加普适性。通过本发明的插件***实现机制,可以让golang开发的项目实现业务逻辑与基础框架的解耦。
本公开实施例还提供一种如图4所示的插件编译装置,所述装置包括:
配置信息获取模块401,用于获取与待编译的插件代码块对应的配置信息,所述配置信息包括所述插件代码块内定义的每个函数和每个函数的索引标识。例如,配置信息获取模块401可以用于执行图2中的S201。
函数生成模块402,用于根据所述每个函数和每个函数的索引标识,生成导出函数代码块,所述导出函数用于根据所述插件代码块生成插件对象,并返回所述插件对象的指针给宿主程序,以及根据所述每个函数和每个函数的索引标识对预先定义在所述宿主程序中的与所述插件对象相对应的插件子类中的函数映射进行赋值。例如,函数生成模块402可以用于执行图2中的S202。
编译模块403,用于对所述导出函数代码块和所述插件代码块进行编译,得到动态库文件,并将所述动态库文件发布到所述宿主程度的指定路径下。例如,编译模块403可以用于执行图2中的S203。
可能的实现方式中,所述函数生成模块402,具体用于:获取模板代码块,所述模板代码块用于实现所述导出函数;将每个函数和每个函数的索引标识渲染到所述模板代码块中,得到所述导出函数代码块。
本公开实施例还提供一种如图5所示的插件调用装置,所述装置包括:
请求接收模块501,用于接收插件调用请求,所述插件调用请求包括目标插件标识和目标索引标识。例如,请求接收模块501可以用于执行图3中的S301。
插件对象确定模块502,用于根据所述目标插件标识,确定目标插件对象以及预先定义在宿主程序中的与所述目标插件对象相对应的插件子类,所述目标插件对象中的函数具有索引标识,所述插件子类包括函数映射,所述函数映射包括所述目标插件对象中的每个函数的索引标识到对应函数的映射。例如,插件对象确定模块502可以用于执行图3中的S302。
函数确定模块503,用于从所述插件子类的所述函数映射中,确定与所述目标索引标识对应的目标函数。例如,函数确定模块503可以用于执行图3中的S303。
函数调用模块504,用于对所述目标插件对象中的所述目标函数进行调用。例如,函数调用模块504可以用于执行图3中的S304。
可能的实现方式中,还包括:加载模块,用于加载动态库文件,所述动态库文件与所述目标插件对象对应,所述动态库文件包括导出函数和插件代码块,所述导出函数包括所述插件代码块内的每个函数和每个函数的所述索引标识;导出模块,用于调用所述导出函数,以通过所述导出函数,根据所述插件代码块生成所述目标插件对象,并获取所述目标插件对象的指针,以及根据所述插件代码块内的每个函数和每个函数的所述索引标识,对所述目标插件对象对应的插件子类中的函数映射进行赋值。
可能的实现方式中,所述装置还包括:对应关系建立模块,用于建立所述目标插件对象的指针与所述目标插件标识之间的对应关系。
可能的实现方式中,所述插件对象确定模块,具体用于:根据预先建立的插件对象的指针与插件标识之间的对应关系,确定与所述目标插件标识对应的指针,所述目标插件标识对应的指针所指向的插件对象为所述目标插件对象;根据所述目标插件对象的类型,将所述目标插件标识对应的指针转换成对应插件子类的指针,所述对应插件子类的指针所指向的插件子类为所述目标插件对象对应的插件子类。
可能的实现方式中,所述宿主程序具有第一变量空间,所述第一变量空间包括所述宿主程序的每个插件对象的变量;所述装置还包括:第一操作模块,用于通过所述第一变量空间预设的变量操作接口,响应第一插件对象根据第一插件对象标识或者第二插件对象标识对所述第一变量空间中对应插件对象的变量执行的操作,所述第一插件对象为所述宿主程序的任意插件对象,所述第二插件对象为除所述第一插件对象以外的任意插件对象,所述操作包括获取变量的操作、设置变量的操作以及删除变量的操作。
可能的实现方式中,所述宿主程序具有第二变量空间,所述第二变量空间中包括所述宿主程序对所述宿主程序的插件对象开放的宿主函数;所述装置还包括:第二操作模块,用于通过所述第二变量空间预设的函数调用接口,响应任意插件对象根据目标宿主函数的函数标识对所述第二变量空间中的目标宿主函数的调用。
可能的实现方式中,所述第二变量空间中还包括第二变量空间中还包括所述宿主程序对所述宿主程序的插件对象开放的宿主变量,所述第二操作模块,还用于:通过所述第二变量空间预设的变量操作接口,响应任意插件对象对所述第二变量空间中任意变量的操作,所述操作包括获取变量的操作和设置变量的操作。
可能的实现方式中,所述加载模块,具体用于:监听指定路径下的文件信息;当监听到新增的动态库文件时,加载所述新增的动态库文件。
可能的实现方式中,所述宿主程序定义有插件基类,所述插件基类中定义有至少一种类型的插件对象公共的函数和属性,每种类型的插件对象所对应的插件子类继承所述插件基类。
可能的实现方式中,所述目标插件对象中的每个函数的索引标识为所述目标插件对象对应的插件子类中声明的函数标识。
本公开的实施例提供的技术方案至少带来以下有益效果:
在开发阶段,预先在宿主程序中定义插件基类和每种类型插件对应的插件子类,基类中包含各类型插件所必须的方法和属性,子类继承该基类并根据具体的业务场景定义业务函数的函数原型。插件子类中还包括函数映射。
在编译阶段,首先提供一个供编译器读取的配置文件,配置文件中除了包括插件的基础描述信息外,关键还包括插件内定义的每个函数及其索引标识(是指插件子类中声明的函数标识)。编译器首先根据该配置文件生成导出函数代码,并生成包含该导出函数代码和插件代码的动态库文件,添加到宿主程序中。
在插件加载阶段,宿主程序在加载完该动态库文件后,会通过前述导出函数,生成插件对象并返回插件对象的指针给到宿主程序,宿主程序则会建立插件指针与插件标识之间的对应关系。同时,导出函数还会对插件子类内部的函数映射进行赋值,使得函数映射中包括插件的每个函数的索引标识到对应函数的映射。
在插件调用阶段,可以根据目标插件标识和目标索引标识,请求调用目标插件对象内定义的目标函数。宿主程序接收到插件调用请求后,首先确定与目标插件标识对应的目标插件对象和目标插件对象相对应的插件子类;再访问插件子类内部的函数映射,以确定与目标索引标识对应的目标函数,最后对目标插件对象中的目标函数进行调用。
宿主程序与插件通过这种调用机制,可以实现插件内的各种业务功能,同时业务插件有新增或删减函数时,只需发布编译好的动态库文件,宿主程序自动热加载,宿主程序无需任何变动,实现框架与业务逻辑的解耦。本公开技术方案实现了在开发阶段插件与宿主程序解耦,部署阶段插件功能与宿主程序的功能融合。
关于上述实施例中的装置,其中各个模块执行操作的具体方式已经在有关该方法的实施例中进行了详细描述,此处将不做详细阐述说明。
本公开实施例还提供了一种电子设备,图6是本公开提供的一种电子设备的结构示意图。如图6,该电子设备10可以包括至少一个处理器101以及用于存储处理器可执行指令的存储器103。其中,处理器101被配置为执行存储器103中的指令,以实现上述实施例中的插件调用方法。
另外,电子设备10还可以包括通信总线102以及至少一个通信接口104。
处理器101可以是一个处理器(central processing units,CPU),微处理单元,ASIC,或一个或多个用于控制本公开方案程序执行的集成电路。
通信总线102可包括一通路,在上述组件之间传送信息。
通信接口104,使用任何收发器一类的装置,用于与其他设备或通信网络通信,如以太网,无线接入网(radio access network,RAN),无线局域网(wireless local areanetworks,WLAN)等。
存储器103可以是只读存储器(read-only memory,ROM)或可存储静态信息和指令的其他类型的静态存储设备,随机存取存储器(random access memory,RAM)或者可存储信息和指令的其他类型的动态存储设备,也可以是电可擦可编程只读存储器(electricallyerasable programmable read-only memory,EEPROM)、只读光盘(compact disc read-only memory,CD-ROM)或其他光盘存储、光碟存储(包括压缩光碟、激光碟、光碟、数字通用光碟、蓝光光碟等)、磁盘存储介质或者其他磁存储设备、或者能够用于携带或存储具有指令或数据结构形式的期望的程序代码并能够由计算机存取的任何其他介质,但不限于此。存储器可以是独立存在,通过总线与处理单元相连接。存储器也可以和处理单元集成在一起。
其中,存储器103用于存储执行本公开方案的指令,并由处理器101来控制执行。处理器101用于执行存储器103中存储的指令,从而实现本公开方法中的功能。
在具体实现中,作为一种实施例,处理器101可以包括一个或多个CPU,例如图1中的CPU0和CPU1。
在具体实现中,作为一种实施例,电子设备10可以包括多个处理器,例如图6中的处理器101和处理器107。这些处理器中的每一个可以是一个单核(single-CPU)处理器,也可以是一个多核(multi-CPU)处理器。这里的处理器可以指一个或多个设备、电路、和/或用于处理数据(例如计算机程序指令)的处理核。
在具体实现中,作为一种实施例,电子设备10还可以包括输出设备105和输入设备106。输出设备105和处理器101通信,可以以多种方式来显示信息。例如,输出设备105可以是液晶显示器(liquid crystal display,LCD),发光二级管(light emitting diode,LED)显示设备,阴极射线管(cathode ray tube,CRT)显示设备,或投影仪(projector)等。输入设备106和处理器101通信,可以以多种方式接受用户的输入。例如,输入设备106可以是鼠标、键盘、触摸屏设备或传感设备等。
另外,本公开还提供一种计算机可读存储介质,当计算机可读存储介质中的指令由服务器的处理器执行时,使得服务器能够执行如上述实施例所提供的方法。
另外,本公开还提供一种计算机程序产品,包括计算机指令,当计算机指令在服务器上运行时,使得服务器执行如上述实施例所提供的方法。
本领域技术人员在考虑说明书及实践这里公开的发明后,将容易想到本公开的其它实施方案。本申请旨在涵盖本公开的任何变型、用途或者适应性变化,这些变型、用途或者适应性变化遵循本公开的一般性原理并包括本公开未公开的本技术领域中的公知常识或惯用技术手段。说明书和实施例仅被视为示例性的,本公开的真正范围和精神由下面的权利要求指出。
应当理解的是,本公开并不局限于上面已经描述并在附图中示出的精确结构,并且可以在不脱离其范围进行各种修改和改变。本公开的范围仅由所附的权利要求来限制。
Claims (24)
1.一种插件调用方法,其特征在于,包括:
加载动态库文件,所述动态库文件与目标插件对象对应,所述动态库文件包括导出函数和插件代码块,所述导出函数包括所述插件代码块内的每个函数和每个函数的索引标识;
调用所述导出函数,以通过所述导出函数,根据所述插件代码块生成所述目标插件对象,并获取所述目标插件对象的指针,以及根据所述插件代码块内的每个函数和每个函数的所述索引标识,对所述目标插件对象对应的插件子类中的函数映射进行赋值;
接收插件调用请求,所述插件调用请求包括目标插件标识和目标索引标识;
根据所述目标插件标识,确定目标插件对象以及预先定义在宿主程序中的与所述目标插件对象相对应的插件子类,所述目标插件对象中的函数具有索引标识,所述插件子类包括函数映射,所述函数映射包括所述目标插件对象中的每个函数的索引标识到对应函数的映射;
从所述插件子类的所述函数映射中,确定与所述目标索引标识对应的目标函数;
对所述目标插件对象中的所述目标函数进行调用。
2.根据权利要求1所述的插件调用方法,其特征在于,所述调用所述导出函数之后,所述方法还包括:
建立所述目标插件对象的指针与所述目标插件标识之间的对应关系。
3.根据权利要求1所述的插件调用方法,其特征在于,所述加载动态库文件,包括:
监听指定路径下的文件信息;
当监听到新增的动态库文件时,加载所述新增的动态库文件。
4.根据权利要求1-3任一项所述的插件调用方法,其特征在于,所述根据所述目标插件标识,确定目标插件对象以及预先定义在宿主程序中的与所述目标插件对象相对应的插件子类,包括:
根据预先建立的插件对象的指针与插件标识之间的对应关系,确定与所述目标插件标识对应的指针,所述目标插件标识对应的指针所指向的插件对象为所述目标插件对象;
根据所述目标插件对象的类型,将所述目标插件标识对应的指针转换成对应插件子类的指针,所述对应插件子类的指针所指向的插件子类为所述目标插件对象对应的插件子类。
5.根据权利要求1-3任一项所述的插件调用方法,其特征在于,所述宿主程序具有第一变量空间,所述第一变量空间包括所述宿主程序的每个插件对象的变量;所述方法还包括:
通过所述第一变量空间预设的变量操作接口,响应第一插件对象根据第一插件对象标识或者第二插件对象标识对所述第一变量空间中对应插件对象的变量执行的操作,所述第一插件对象为所述宿主程序的任意插件对象,所述第二插件对象为除所述第一插件对象以外的任意插件对象,所述操作包括获取变量的操作、设置变量的操作以及删除变量的操作。
6.根据权利要求1-3任一项所述的插件调用方法,其特征在于,所述宿主程序具有第二变量空间,所述第二变量空间中包括所述宿主程序对所述宿主程序的每个插件对象开放的宿主函数;所述方法还包括:
通过所述第二变量空间预设的函数调用接口,响应任意插件对象根据目标宿主函数的函数标识对所述第二变量空间中的目标宿主函数的调用。
7.根据权利要求6所述的插件调用方法,其特征在于,所述第二变量空间中还包括所述宿主程序对每个所述插件对象开放的宿主变量,所述方法还包括:
通过所述第二变量空间预设的变量操作接口,响应任意插件对象对所述第二变量空间中任意变量的操作,所述操作包括获取变量的操作和设置变量的操作。
8.根据权利要求1-3任一项所述的插件调用方法,其特征在于,所述宿主程序定义有插件基类,所述插件基类中定义有至少一种类型的插件对象公共的函数和属性,每种类型的插件对象所对应的插件子类继承所述插件基类。
9.根据权利要求1所述的插件调用方法,其特征在于,所述目标插件对象中的每个函数的索引标识为所述目标插件对象对应的插件子类中声明的函数标识。
10.一种插件编译方法,其特征在于,所述方法包括:
获取与待编译的插件代码块对应的配置信息,所述配置信息包括所述插件代码块内定义的每个函数和每个函数的索引标识;
根据所述每个函数和每个函数的索引标识,生成导出函数代码块,所述导出函数用于根据所述插件代码块生成插件对象,并返回所述插件对象的指针给宿主程序,以及根据所述每个函数和每个函数的索引标识,对预先定义在所述宿主程序中的与所述插件对象对应的插件子类中的函数映射进行赋值;
对所述导出函数代码块和所述插件代码块进行编译,得到动态库文件,并将所述动态库文件发布到所述宿主程序的指定路径下。
11.根据权利要求10所述的插件编译方法,其特征在于,所述根据待编译的插件代码块内定义的每个函数的索引标识,生成导出函数代码块,包括:
获取模板代码块,所述模板代码块用于实现所述导出函数;
将所述每个函数和每个函数的索引标识渲染到所述模板代码块中,得到所述导出函数代码块。
12.一种插件调用装置,其特征在于,包括:
加载模块,用于加载动态库文件,所述动态库文件与目标插件对象对应,所述动态库文件包括导出函数和插件代码块,所述导出函数包括所述插件代码块内的每个函数和每个函数的索引标识;
导出模块,用于调用所述导出函数,以通过所述导出函数,根据所述插件代码块生成所述目标插件对象,并获取所述目标插件对象的指针,以及根据所述插件代码块内的每个函数和每个函数的所述索引标识,对所述目标插件对象对应的插件子类中的函数映射进行赋值;
请求接收模块,用于接收插件调用请求,所述插件调用请求包括目标插件标识和目标索引标识;
插件对象确定模块,用于根据所述目标插件标识,确定目标插件对象以及预先定义在宿主程序中的与所述目标插件对象相对应的插件子类,所述目标插件对象中的函数具有索引标识,所述插件子类包括函数映射,所述函数映射包括所述目标插件对象中的每个函数的索引标识到对应函数的映射;
函数确定模块,用于从所述插件子类的所述函数映射中,确定与所述目标索引标识对应的目标函数;
函数调用模块,用于对所述目标插件对象中的所述目标函数进行调用。
13.根据权利要求12所述的插件调用装置,其特征在于,所述装置还包括:
对应关系建立模块,用于建立所述目标插件对象的指针与所述目标插件标识之间的对应关系。
14.根据权利要求12所述的插件调用装置,其特征在于,所述加载模块,具体用于:
监听指定路径下的文件信息;
当监听到新增的动态库文件时,加载所述新增的动态库文件。
15.根据权利要求12-14任一项所述的插件调用装置,其特征在于,所述插件对象确定模块,具体用于:
根据预先建立的插件对象的指针与插件标识之间的对应关系,确定与所述目标插件标识对应的指针,所述目标插件标识对应的指针所指向的插件对象为所述目标插件对象;
根据所述目标插件对象的类型,将所述目标插件标识对应的指针转换成对应插件子类的指针,所述对应插件子类的指针所指向的插件子类为所述目标插件对象对应的插件子类。
16.根据权利要求12-14任一项所述的插件调用装置,其特征在于,所述宿主程序具有第一变量空间,所述第一变量空间包括所述宿主程序的每个插件对象的变量;
所述装置还包括:
第一操作模块,用于通过所述第一变量空间预设的变量操作接口,响应第一插件对象根据第一插件对象标识或者第二插件对象标识对所述第一变量空间中对应插件对象的变量执行的操作,所述第一插件对象为所述宿主程序的任意插件对象,所述第二插件对象为除所述第一插件对象以外的任意插件对象,所述操作包括获取变量的操作、设置变量的操作以及删除变量的操作。
17.根据权利要求12-14任一项所述的插件调用装置,其特征在于,所述宿主程序具有第二变量空间,所述第二变量空间中包括所述宿主程序对所述宿主程序的每个插件对象开放的宿主函数;
所述装置还包括:
第二操作模块,用于通过所述第二变量空间预设的函数调用接口,响应任意插件对象根据目标宿主函数的函数标识对所述第二变量空间中的目标宿主函数的调用。
18.根据权利要求17所述的插件调用装置,其特征在于,所述第二变量空间中还包括所述宿主程序对每个所述插件对象开放的宿主变量,所述第二操作模块,还用于:
通过所述第二变量空间预设的变量操作接口,响应任意插件对象对所述第二变量空间中任意变量的操作,所述操作包括获取变量的操作和设置变量的操作。
19.根据权利要求12-14任一项所述的插件调用装置,其特征在于,所述宿主程序定义有插件基类,所述插件基类中定义有至少一种类型的插件对象公共的函数和属性,每种类型的插件对象所对应的插件子类继承所述插件基类。
20.根据权利要求12所述的插件调用装置,其特征在于,所述目标插件对象中的每个函数的索引标识为所述目标插件对象对应的插件子类中声明的函数标识。
21.一种插件编译装置,其特征在于,所述装置包括:
配置信息获取模块,用于获取与待编译的插件代码块对应的配置信息,所述配置信息包括所述插件代码块内定义的每个函数和每个函数的索引标识;
函数生成模块,用于根据所述每个函数的索引标识,生成导出函数代码块,所述导出函数用于根据所述插件代码块生成插件对象,并返回所述插件对象的指针给宿主程序,以及根据所述每个函数的索引标识对预先定义在所述宿主程序中的与所述插件对象相对应的插件子类中的函数映射进行赋值;
编译模块,用于对所述导出函数代码块和所述插件代码块进行编译,得到动态库文件,并将所述动态库文件发布到所述宿主程序的指定路径下。
22.根据权利要求21所述的插件编译装置,其特征在于,所述函数生成模块,具体用于:
获取模板代码块,所述模板代码块用于实现所述导出函数;
将每个函数和每个函数的索引标识渲染到所述模板代码块中,得到所述导出函数代码块。
23.一种电子设备,其特征在于,包括:
处理器和用于存储所述处理器可执行指令的存储器;其中,所述处理器被配置为执行所述可执行指令,以实现如权利要求1至9中任一项所述的方法,或者实现如权利要求10或11所述的方法。
24.一种计算机可读存储介质,其特征在于,当所述计算机可读存储介质中的指令由装置执行时,使得装置能够执行如权利要求1至9中任一项所述的方法或者如权利要求10或11所述的方法;当所述计算机可读存储介质中的指令由电子设备的处理器执行时,使得电子设备的处理器能够执行如权利要求1至9中任一项所述的方法或者如权利要求10或11所述的方法。
Priority Applications (1)
Application Number | Priority Date | Filing Date | Title |
---|---|---|---|
CN202210482972.3A CN114942796B (zh) | 2022-05-05 | 2022-05-05 | 插件编译及调用方法、装置、设备及存储介质 |
Applications Claiming Priority (1)
Application Number | Priority Date | Filing Date | Title |
---|---|---|---|
CN202210482972.3A CN114942796B (zh) | 2022-05-05 | 2022-05-05 | 插件编译及调用方法、装置、设备及存储介质 |
Publications (2)
Publication Number | Publication Date |
---|---|
CN114942796A CN114942796A (zh) | 2022-08-26 |
CN114942796B true CN114942796B (zh) | 2024-07-02 |
Family
ID=82907758
Family Applications (1)
Application Number | Title | Priority Date | Filing Date |
---|---|---|---|
CN202210482972.3A Active CN114942796B (zh) | 2022-05-05 | 2022-05-05 | 插件编译及调用方法、装置、设备及存储介质 |
Country Status (1)
Country | Link |
---|---|
CN (1) | CN114942796B (zh) |
Families Citing this family (5)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
CN115185712B (zh) * | 2022-09-08 | 2022-12-27 | 中化现代农业有限公司 | 数据交互方法、装置、电子设备和存储介质 |
CN115373763B (zh) * | 2022-10-24 | 2023-02-17 | 北京达佳互联信息技术有限公司 | 插件加载方法、装置、电子设备及存储介质 |
CN115794040B (zh) * | 2022-11-14 | 2024-02-06 | 深圳十沣科技有限公司 | 构造cae软件架构的方法、装置、设备及存储介质 |
CN116991380B (zh) * | 2023-09-21 | 2024-01-09 | 腾讯科技(深圳)有限公司 | 一种应用程序的构建方法、装置、电子设备及存储介质 |
CN118245139A (zh) * | 2024-05-30 | 2024-06-25 | 北京基调网络股份有限公司 | 探针处理方法、装置、存储介质及电子设备 |
Citations (2)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
CN110704035A (zh) * | 2019-10-17 | 2020-01-17 | 北京首贝科技发展有限公司 | 一种组插件式软件架构***及其实现方法 |
CN110928531A (zh) * | 2019-11-19 | 2020-03-27 | 中国电子科技集团公司第四十一研究所 | 一种电磁频谱监测***软件平台构建方法 |
Family Cites Families (12)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
US7516159B2 (en) * | 2004-08-10 | 2009-04-07 | Palo Alto Research Center Incorporated | Extension of XQuery in a high performance XML/XQuery database |
US7996830B2 (en) * | 2006-06-05 | 2011-08-09 | International Business Machines Corporation | Programming model generic application deployment |
CN102520967A (zh) * | 2011-12-28 | 2012-06-27 | 深圳市融创天下科技股份有限公司 | 一种创建与使用移动平台插件的方法、***和移动终端 |
CN105912362B (zh) * | 2016-04-11 | 2019-02-26 | 珠海豹趣科技有限公司 | 一种加载插件的方法、装置及电子设备 |
CN106155749B (zh) * | 2016-07-28 | 2019-12-31 | 苏州浪潮智能科技有限公司 | 一种监控插件扩展方法及装置 |
US10838920B2 (en) * | 2017-05-05 | 2020-11-17 | Esoptra NV | Plug-in function platform and methods |
US20190129734A1 (en) * | 2017-10-31 | 2019-05-02 | Ca, Inc. | Data collection workflow extension |
CN109460215B (zh) * | 2018-11-13 | 2023-05-26 | 三六零科技集团有限公司 | 应用控制方法及装置 |
CN110162345B (zh) * | 2019-05-05 | 2022-02-18 | 网宿科技股份有限公司 | 一种应用程序访问方法、装置和存储介质 |
CN110531981A (zh) * | 2019-08-27 | 2019-12-03 | 珠海格力智能装备有限公司 | 视觉软件***及其应用方法 |
CN112559083B (zh) * | 2020-12-24 | 2023-08-04 | 成都新希望金融信息有限公司 | 函数插件执行方法、装置、电子设备及存储介质 |
CN114281321A (zh) * | 2021-12-10 | 2022-04-05 | 珠海豹趣科技有限公司 | 一种软件开发快捷编辑方法、装置、电子设备及介质 |
-
2022
- 2022-05-05 CN CN202210482972.3A patent/CN114942796B/zh active Active
Patent Citations (2)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
CN110704035A (zh) * | 2019-10-17 | 2020-01-17 | 北京首贝科技发展有限公司 | 一种组插件式软件架构***及其实现方法 |
CN110928531A (zh) * | 2019-11-19 | 2020-03-27 | 中国电子科技集团公司第四十一研究所 | 一种电磁频谱监测***软件平台构建方法 |
Also Published As
Publication number | Publication date |
---|---|
CN114942796A (zh) | 2022-08-26 |
Similar Documents
Publication | Publication Date | Title |
---|---|---|
CN114942796B (zh) | 插件编译及调用方法、装置、设备及存储介质 | |
US10146522B1 (en) | Live code updates | |
CN108920133B (zh) | 跨语言编程方法、装置、电子设备及存储介质 | |
US20040003388A1 (en) | Preparation of a software configuration using an XML type programming language | |
CN105159788B (zh) | 一种Android应用间动态共享资源的方法及*** | |
CN109032631B (zh) | 应用程序补丁包获取方法、装置、计算机设备及存储介质 | |
CN111399840B (zh) | 一种模块开发方法及装置 | |
CN106648755B (zh) | 一种在安卓art环境中动态加载dex的方法及装置 | |
CN112769706B (zh) | 组件化路由方法及*** | |
CN111736913B (zh) | 类加载方法和装置 | |
CN113986402A (zh) | 函数调用方法、装置、电子设备及存储介质 | |
US10387142B2 (en) | Using annotation processors defined by modules with annotation processors defined by non-module code | |
CN109558121B (zh) | 接口驱动程序的开发方法、装置、设备及存储介质 | |
CN111324395B (zh) | 调用方法、装置和计算机可读存储介质 | |
CN110806891B (zh) | 嵌入式设备软件版本的生成方法及装置 | |
CN114860204B (zh) | 程序处理、运行方法、装置、终端、智能卡及存储介质 | |
CN112612530B (zh) | 类查询方法及装置 | |
CN114064176A (zh) | 一种视图交互方法、装置、电子设备及计算机可读介质 | |
US8082553B2 (en) | Client management of java management extensions (JMX) Mbean state | |
CN111506301B (zh) | 绕过***限制反射调用的方法及相关设备 | |
CN115827140B (zh) | 可视化大屏的生成方法、装置、设备及存储介质 | |
US20240004616A1 (en) | Runtime support for role types that extend underlying types | |
CN114416219B (zh) | ***函数调用方法、装置、电子设备及可读介质 | |
US20080005160A1 (en) | Assembly Sensitive Dynamic Classloading Of .Net Types in J# | |
CN115857962A (zh) | 软件项目处理方法、装置、电子设备以及可读存储介质 |
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 |