一种基于C语言预处理器实现的动态链接库反射方法及系统与流程

未命名 07-13 阅读:73 评论:0

一种基于c语言预处理器实现的动态链接库反射方法及系统
技术领域
1.本发明涉及动态链接库反射技术领域,更具体地,涉及一种基于c语言预处理器实现的动态链接库反射方法及系统。


背景技术:

2.在计算机软件的开发过程中,使用c/c++等语言开发出的动态链接库的链接过程具有很多不可控性,因为不同的库模块可能使用不同的语法标准,不同版本的产品需要的库模块版本也不同,需要使用不同版本的编译器进行编译,在运行时需要不同版本的运行时,使得计算机软件在编译或者运行时都可能会出现不可预知的错误,尤其是在使用低版本编译器编译的软件链接高版本编译器编译的动态链接库时。
3.现有技术公开了一种用于编译java文件的编译方法及装置,方法包括以下:获取待编译的java文件包;解析所述java文件包,得到解析信息,所述解析信息为所述java文件包中各个基础单元组成信息;对所述java文件包进行等同格式转化,在所述等同格式转化中对所述解析信息加入自定义标识并排序,以得到改造信息;将所述改造信息通过对应编译器进行编译。该现有技术实现的是对java文件进行编译转换,没有解决c语言开发中动态库在链接过程中或链接后导致运行过程中产生的兼容性问题。


技术实现要素:

4.本发明提供一种基于c语言预处理器实现的动态链接库反射方法及系统,解决了该动态库在链接过程中或链接后导致运行过程中产生的兼容性问题。
5.本发明的首要目的是为解决上述技术问题,本发明的技术方案如下:
6.一种基于c语言预处理器实现的动态链接库反射方法,包括以下步骤:
7.s1:获取需要代理的动态链接库的文件名、需要代理的函数列表,所述函数列表包括:各函数的函数名、返回类型以及参数类型;
8.s2:利用c语言的宏定义构建注册器,所述注册器的输入为动态链接库的文件名,需要代理的函数名,返回类型,参数类型;
9.s3:通过编译器在编译期的预处理过程中利用所述注册器生成代理函数。
10.s4:使用步骤3所述注册器,在源代码中注册需要代理的函数;
11.s5:在业务中调用s1中需要代理的函数,与步骤s4中的注册代码一起编译并运行软件。
12.进一步的,步骤s3的具体过程为:
13.s3.1:使用宏定义声明参数类型转发器,实现参数类型的转发;
14.s3.2:使用宏定义声明参数转发器,实现参数的转发;
15.s3.3:使用宏定义声明注册器,将返回值类型,函数名称,参数类型,动态链接库名称作为输入参数,实现代理函数的展开。
16.进一步的,使用宏定义声明参数类型转发器具体步骤为:
17.s311:实现能够在多次宏展开中拼接参数的拼接函数,用于将还原后的所有参数类型和参数名称列表拼接到一起;
18.s312:实现能够获取参数列表长度的宏函数,用于确定还原参数列表的递归深度
19.s313:为不同长度的参数列表声明还原参数类型和名称的宏定义,使用步骤s312的递归深度,递归展开参数列表,并使用s311步的拼接函数在递归过程中拼接结果,生成预设格式的展开内容。
20.进一步的,步骤s313中所述的预设格式为type1arg1,type2arg2,type3arg3,...typen argn,其中n表示正整数。
21.进一步的,使用宏定义声明参数转发器具体步骤为:为不同长度的参数列表声明还原参数名称的宏定义,使用步骤s312的递归深度,递归展开参数列表,并使用骤s311中的拼接函数在递归过程中拼接结果,生成第二预设格式的展开内容。
22.进一步的,所述第二预设格式为:arg1,arg2,arg3,...argm,其中m表示正整数。
23.进一步的,步骤s3.3使用宏定义声明注册器,将返回值类型,函数名称,参数类型,动态链接库名称作为输入参数,实现代理函数的展开,具体步骤为:
24.s331:使用输入的返回值类型,函数名称,和将参数类型通过步骤s3.1中参数类型转发器转发出的参数类型和参数名称的列表定义代理函数,生成预设格式的代理函数;
25.s332:在步骤s331步定义的代理函数中使用typedef,根据步骤3.3中输入的返回值类型,函数名称声明函数指针类型,生成预设格式的函数指针类型;
26.s333:根据步骤s3.3步输入的动态链接库的文件名使用loadlibrary加载动态链接库,获取动态链接库的句柄;
27.s334:根据s3.3步输入的函数名称和s333步获取的动态链接库的句柄,使用getprocaddress,获取动态链接库中该函数的地址;
28.s335:将步骤s334步获取到的函数地址转换为步骤s332步声明的函数指针类型,获取函数指针对象;
29.s336:使用步骤s3.2步参数转发器转发出的参数值,调用步骤s335步获取到的函数指针,并返回调用该函数指针返回的返回值。
30.进一步的,预设格式的代理函数为:int func(type1arg1,type2arg2,type3arg3,...typen argn){},int表示数据类型,func表示函数名,type参数类型,arg表示函数参数。
31.进一步的,预设格式的函数指针类型为:typedef int(*_func)(type1,type2,type3,...typen)。
32.本发明第二方面提供了一种基于c语言预处理器实现的动态链接库反射系统,该系统包括:存储器、处理器,所述存储器中包括一种基于c语言预处理器实现的动态链接库反射方法程序,所述一种基于c语言预处理器实现的动态链接库反射方法程序被所述处理器执行时实现如下步骤:
33.s1:获取需要代理的动态链接库的文件名、需要代理的函数列表,所述函数列表包括:各函数的函数名、返回类型以及参数类型;
34.s2:利用c语言的宏定义构建注册器,所述注册器的输入为动态链接库的文件名,需要代理的函数名,返回类型,参数类型;
35.s3:通过编译器在编译期的预处理过程中利用所述注册器生成代理函数。
36.s4:使用步骤3所述注册器,在源代码中注册需要代理的函数;
37.s5:在业务中调用s1中需要代理的函数,与步骤s4中的注册代码一起编译并运行软件。
38.与现有技术相比,本发明技术方案的有益效果是:
39.本发明通过使用c语言预处理器注册动态链接库的接口,在编译过程中自动生成该接口的代理实现,并使用该代理实现代替动态链接库参与链接过程,从而解决了产品使用不同版本库模块,或同一产品不同版本使用使用该库模块时带来的兼容性问题。
附图说明
40.图1为本发明实施例基于c语言预处理器实现的动态链接库反射方法流程图。
41.图2为本发明实施例注册器注册的函数编译生成代理函数流程图。
42.图3为本发明实施例使用宏定义声明参数类型转发器流程图。
43.图4为本发明实施例使用宏定义声明注册器并实现代理函数的展开的流程图。
具体实施方式
44.为了能够更清楚地理解本发明的上述目的、特征和优点,下面结合附图和具体实施方式对本发明进行进一步的详细描述。需要说明的是,在不冲突的情况下,本技术的实施例及实施例中的特征可以相互组合。
45.在下面的描述中阐述了很多具体细节以便于充分理解本发明,但是,本发明还可以采用其他不同于在此描述的其他方式来实施,因此,本发明的保护范围并不受下面公开的具体实施例的限制。
46.实施例1
47.如图1所示,一种基于c语言预处理器实现的动态链接库反射方法,包括以下步骤:
48.s1:获取需要代理的动态链接库的文件名、需要代理的函数列表,所述函数列表包括:各函数的函数名、返回类型以及参数类型;
49.需要说明的是,本发明动态链接库及其符号库不实际参与软件编译过程中的链接步骤,由c语言预处理器实现的代理实现参与链接。
50.s2:利用c语言的宏定义构建注册器,所述注册器的输入为动态链接库的文件名,需要代理的函数名,返回类型,参数类型;
51.需要说明的是,本发明使用c语言中的宏定义实现一个注册器,该注册器通过输入接口名称,返回值类型,参数类型,实现反射动态链接库中的接口;使用c语言宏定义实现的注册器,能够通过接口名称,返回值类型,参数类型生成一个名称,返回值,参数类型相同的代理接口的函数实现,并且支持不同长度参数及可变长度参数类型的注册。
52.实施例2
53.基于上述步骤本实施例详细阐述利用所述注册器注册的函数编译生成代理函数,需要说明的是,该注册器的实现是本发明的核心部件,本质是一个使用c语言预处理实现的函数,可以处理不同长度以及可变长度的参数类型,通过该注册器注册的函数会在编译时自动生成一个代理函数。
54.s3:通过编译器在编译期的预处理过程中利用所述注册器生成代理函数。
55.需要说明的是,本发明中基于该注册器实现的反射机制,在源码中将需要进行代理访问的接口进行注册,由c语言编译器中的预处理自动生成访问动态链接库中同名接口的代理实现,然后参与编译;
56.如图2所示,步骤s3的具体过程为:
57.s3.1:使用宏定义声明参数类型转发器,实现参数类型的转发;
58.需要说明的是,参数类型转发器是实现注册器的关键步骤,用于将注册器输入中的参数类型列表展开,还原所有的参数类型,同时为每一个参数类型依次生成参数名称,是步骤s3中自动生成代理函数的必要条件。
59.如图3所示,使用宏定义声明参数类型转发器具体步骤为:
60.s311:实现能够在多次宏展开中拼接参数的拼接函数,用于将还原后的所有参数类型和参数名称列表拼接到一起;
61.s312:实现能够获取参数列表长度的宏函数,用于确定还原参数列表的递归深度
62.s313:为不同长度的参数列表声明还原参数类型和名称的宏定义,使用步骤s312的递归深度,递归展开参数列表,并使用s311步的拼接函数在递归过程中拼接结果,生成预设格式的展开内容。
63.步骤s313中所述的预设格式为type1arg1,type2arg2,type3arg3,...typen argn,其中n表示正整数。
64.s3.2:使用宏定义声明参数转发器,实现参数的转发;
65.需要说明的是,参数转发器是实现注册器的关键步骤,用于将生成与步骤s3.1中展开的参数列表中相同参数名称,是步骤s3步中自动生成代理函数的必要条件。
66.使用宏定义声明参数转发器具体步骤为:为不同长度的参数列表声明还原参数名称的宏定义,使用步骤s312的递归深度,递归展开参数列表,并使用骤s311中的拼接函数在递归过程中拼接结果,生成第二预设格式的展开内容。
67.所述第二预设格式为:arg1,arg2,arg3,...argm,其中m表示正整数。
68.s3.3:使用宏定义声明注册器,将返回值类型,函数名称,参数类型,动态链接库名称作为输入参数,实现代理函数的展开。
69.入图3所示,具体步骤为:
70.s331:使用输入的返回值类型,函数名称,和将参数类型通过步骤s3.1中参数类型转发器转发出的参数类型和参数名称的列表定义代理函数,生成预设格式的代理函数;
71.预设格式的代理函数为:int func(type1arg1,type2arg2,type3arg3,...typen argn){},int表示数据类型,func表示函数名,type参数类型,arg表示函数参数。
72.s332:在步骤s331步定义的代理函数中使用typedef,根据步骤3.3中输入的返回值类型,函数名称声明函数指针类型,生成预设格式的函数指针类型;
73.预设格式的函数指针类型为:typedef int(*_func)(type1,type2,type3,...typen)。
74.s333:根据步骤s3.3步输入的动态链接库的文件名使用loadlibrary加载动态链接库,获取动态链接库的句柄;
75.s334:根据s3.3步输入的函数名称和s333步获取的动态链接库的句柄,使用
getprocaddress,获取动态链接库中该函数的地址;
76.s335:将步骤s334步获取到的函数地址转换为步骤s332中声明的函数指针类型,获取函数指针对象;
77.s336:使用步骤s3.2步参数转发器转发出的参数值,调用步骤s335步获取到的函数指针,并返回调用该函数指针返回的返回值。
78.s4:使用步骤3所述注册器,在源代码中注册需要代理的函数;
79.s5:在业务中调用s1中需要代理的函数,与步骤s4中的注册代码一起编译并运行软件。
80.需要说明的是,动态链接库在软件运行时被动态加载,动态链接库中的接口通过c语言预处理器自动生成的代理接口实现访问;
81.访问接口时,通过注册机制获取到接口的名称,动态获取动态链接库中同名的接口的函数地址,通过注册机制根据接口名称,返回值,参数类型,构造出可以调用的和原函数完全相同的函数指针对象,并将该函数地址转换为转函数指针,完成调用。
82.实施例3
83.本发明第二方面提供了一种基于c语言预处理器实现的动态链接库反射系统,该系统包括:存储器、处理器,所述存储器中包括一种基于c语言预处理器实现的动态链接库反射方法程序,所述一种基于c语言预处理器实现的动态链接库反射方法程序被所述处理器执行时实现如下步骤:
84.s1:获取需要代理的动态链接库的文件名、需要代理的函数列表,所述函数列表包括:各函数的函数名、返回类型以及参数类型;
85.s2:利用c语言的宏定义构建注册器,所述注册器的输入为动态链接库的文件名,需要代理的函数名,返回类型,参数类型;
86.s3::通过编译器在编译期的预处理过程中利用所述注册器生成代理函数。
87.s4:使用步骤3所述注册器,在源代码中注册需要代理的函数;
88.s5:在业务中调用s1中需要代理的函数,与步骤s4中的注册代码一起编译并运行软件。
89.本发明使用了c语言预处理来动态反射动态链接库中的接口,通过动态调用动态链接库的接口,屏蔽了动态链接库及其符号库参与软件的链接过程,解决了产品使用不同版本库模块,或同一产品不同版本使用使用该库模块时带来的兼容性问题。
90.显然,本发明的上述实施例仅仅是为清楚地说明本发明所作的举例,而并非是对本发明的实施方式的限定。对于所属领域的普通技术人员来说,在上述说明的基础上还可以做出其它不同形式的变化或变动。这里无需也无法对所有的实施方式予以穷举。凡在本发明的精神和原则之内所作的任何修改、等同替换和改进等,均应包含在本发明权利要求的保护范围之内。

技术特征:
1.一种基于c语言预处理器实现的动态链接库反射方法,其特征在于,包括以下步骤:s1:获取需要代理的动态链接库的文件名、需要代理的函数列表,所述函数列表包括:各函数的函数名、返回类型以及参数类型;s2:利用c语言的宏定义构建注册器,所述注册器的输入为动态链接库的文件名,需要代理的函数名,返回类型,参数类型;s3:通过编译器在编译期的预处理过程中利用所述注册器生成代理函数。s4:使用步骤s3所述注册器,在源代码中注册需要代理的函数;s5:在业务中调用s1中需要代理的函数,与步骤s4中的注册代码一起编译并运行软件。2.根据权利要求1所述的一种基于c语言预处理器实现的动态链接库反射方法,其特征在于,步骤s3的具体过程为:s3.1:使用宏定义声明参数类型转发器,实现参数类型的转发;s3.2:使用宏定义声明参数转发器,实现参数的转发;s3.3:使用宏定义声明注册器,将返回值类型,函数名称,参数类型,动态链接库名称作为输入参数,实现代理函数的展开。3.根据权利要求2所述的一种基于c语言预处理器实现的动态链接库反射方法,其特征在于,使用宏定义声明参数类型转发器具体步骤为:s311:实现能够在多次宏展开中拼接参数的拼接函数,用于将还原后的所有参数类型和参数名称列表拼接到一起;s312:实现能够获取参数列表长度的宏函数,用于确定还原参数列表的递归深度;s313:为不同长度的参数列表声明还原参数类型和名称的宏定义,使用步骤s312的递归深度,递归展开参数列表,并使用步骤s311拼接函数在递归过程中拼接结果,生成预设格式的展开内容。4.根据权利要求3所述的一种基于c语言预处理器实现的动态链接库反射方法,其特征在于,步骤s313中所述的预设格式为type1 arg1,type2 arg2,type3arg3,...typen argn,其中n表示正整数。5.根据权利要求3所述的一种基于c语言预处理器实现的动态链接库反射方法,其特征在于,使用宏定义声明参数转发器具体步骤为:为不同长度的参数列表声明还原参数名称的宏定义,使用步骤s312的递归深度,递归展开参数列表,并使用骤s311中的拼接函数在递归过程中拼接结果,生成第二预设格式的展开内容。6.根据权利要求5所述的一种基于c语言预处理器实现的动态链接库反射方法,其特征在于,所述第二预设格式为:arg1,arg2,arg3,...argm,其中m表示正整数。7.根据权利要求2所述的一种基于c语言预处理器实现的动态链接库反射方法,其特征在于,步骤s3.3使用宏定义声明注册器,将返回值类型,函数名称,参数类型,动态链接库名称作为输入参数,实现代理函数的展开,具体步骤为:s331:使用输入的返回值类型,函数名称,和将参数类型通过步骤s3.1中参数类型转发器转发出的参数类型和参数名称的列表定义代理函数,生成预设格式的代理函数;s332:在步骤s331步定义的代理函数中使用typedef,根据步骤3.3中输入的返回值类型,函数名称声明函数指针类型,生成预设格式的函数指针类型;s333:根据步骤s3.3步输入的动态链接库的文件名使用loadlibrary加载动态链接库,
获取动态链接库的句柄;s334:根据s3.3步输入的函数名称和s333步获取的动态链接库的句柄,使用getprocaddress,获取动态链接库中该函数的地址;s335:将步骤s334步获取到的函数地址转换为步骤s332步声明的函数指针类型,获取函数指针对象;s336:使用步骤s3.2步参数转发器转发出的参数值,调用步骤s335步获取到的函数指针,并返回调用该函数指针返回的返回值。8.根据权利要求7所述的一种基于c语言预处理器实现的动态链接库反射方法,其特征在于,预设格式的代理函数为:int func(type1 arg1,type2 arg2,type3arg3,...){},int表示数据类型,func表示函数名,type参数类型,arg表示参数。9.根据权利要求7所述的一种基于c语言预处理器实现的动态链接库反射方法,其特征在于,预设格式的函数指针类型为:typedef int(*_func)(type1,type2,type3,...)。10.一种基于c语言预处理器实现的动态链接库反射系统,其特征在于,该系统包括:存储器、处理器,所述存储器中包括一种基于c语言预处理器实现的动态链接库反射方法程序,所述一种基于c语言预处理器实现的动态链接库反射方法程序被所述处理器执行时实现如下步骤:s1:获取需要代理的动态链接库的文件名、需要代理的函数列表,所述函数列表包括:各函数的函数名、返回类型以及参数类型;s2:利用c语言的宏定义构建注册器,所述注册器的输入为动态链接库的文件名,需要代理的函数名,返回类型,参数类型;s3:通过编译器在编译期的预处理过程中利用所述注册器生成代理函数。s4:使用步骤3所述注册器,在源代码中注册需要代理的函数;s5:在业务中调用s1中需要代理的函数,与步骤s4中的注册代码一起编译并运行软件。

技术总结
本发明公开了一种基于C语言预处理器实现的动态链接库反射方法,包括:S1:获取需要代理的动态链接库的文件名、需要代理的函数列表,所述函数列表包括:各函数的函数名、返回类型以及参数类型;S2:利用C语言的宏定义构建注册器,所述注册器的输入为动态链接库的文件名,需要代理的函数名,返回类型,参数类型;S3:通过编译器在编译期的预处理过程中利用所述注册器生成代理函数。S4:使用步骤S3所述注册器,在源代码中注册需要代理的函数;S5:在业务中调用S1中需要代理的函数,与步骤S4中的注册代码一起编译并运行软件。本发明解决了产品使用不同版本库模块,或同一产品不同版本使用使用该库模块时带来的兼容性问题。该库模块时带来的兼容性问题。该库模块时带来的兼容性问题。


技术研发人员:刘帅帅 郝志刚 李伟
受保护的技术使用者:广州南方卫星导航仪器有限公司
技术研发日:2023.03.09
技术公布日:2023/7/12
版权声明

本文仅代表作者观点,不代表航家之家立场。
本文系作者授权航家号发表,未经原创作者书面授权,任何单位或个人不得引用、复制、转载、摘编、链接或以其他任何方式复制发表。任何单位或个人在获得书面授权使用航空之家内容时,须注明作者及来源 “航空之家”。如非法使用航空之家的部分或全部内容的,航空之家将依法追究其法律责任。(航空之家官方QQ:2926969996)

航空之家 https://www.aerohome.com.cn/

飞机超市 https://mall.aerohome.com.cn/

航空资讯 https://news.aerohome.com.cn/

分享:

扫一扫在手机阅读、分享本文

相关推荐