数据序列化、数据反序列化方法、装置和计算机设备与流程

文档序号:20681302发布日期:2020-05-08 18:25阅读:246来源:国知局
数据序列化、数据反序列化方法、装置和计算机设备与流程

本申请涉及计算机技术领域,特别涉及一种数据序列化、数据反序列化方法、装置和计算机设备。



背景技术:

序列化是指当数据需要存储和传输时,把内存中分散的数据结构转换为连续的字节流的过程。目前,常用的序列化工具有protobuf、xml、json等,然而,这些工具都采用侵入式的序列化方法,开发者需要使用序列化工具指定的数据结构,否则无法实现序列化。

因此,亟需一种能够适用于非指定的数据结构的序列化的方法。



技术实现要素:

本申请实施例提供了一种数据序列化、数据反序列化方法、装置和计算机设备,能够适用于非指定的数据结构的序列化和非序列化处理。

本申请实施例提供了一种数据序列化方法,包括:获取目标代码,其中,目标代码包括用户定义的目标数据的结构体类型定义信息和序列化函数签名;根据目标代码确定序列化函数签名和结构体类型定义信息;根据序列化函数签名和结构体类型定义信息生成目标序列化函数;获取待序列化的目标数据,并根据目标序列化函数对目标数据进行序列化处理,得到对应的目标字节流。

在一个实施例中,目标代码包括中间码;相应的,获取目标代码,包括:获取目标源码,其中,目标源码包括序列化函数签名的源码以及目标数据的结构体类型定义信息的源码;对目标源码进行编译,生成中间码。

在一个实施例中,目标数据的结构体类型定义信息包括多个结构体中各结构体的结构体类型定义信息和指针信息;根据序列化函数签名和结构体类型定义信息生成目标序列化函数,包括:根据序列化函数签名和多个结构体中各结构体的结构体类型定义信息和指针信息生成多个结构体中各个结构体的写入函数;根据各个结构体的写入函数,生成目标序列化函数。

在一个实施例中,根据序列化函数签名和多个结构体中各结构体的结构体类型定义信息和指针信息生成多个结构体中各个结构体的写入函数,包括:按照以下方式生成多个结构体中当前结构体的写入函数:获取上一个结构体的指针信息,并根据上一个结构体的指针信息确定出当前结构体,其中,多个结构体中的第一个结构体是根据序列化函数签名中的第一个参数确定的;根据当前结构体的结构体类型定义信息和指针信息,生成与当前结构体对应的写入函数。

在一个实施例中,该方法还包括:在生成多个结构体中各个结构体的写入函数的过程中,在预设的映射表中记录各结构体以及各结构体对应的写入函数。

在一个实施例中,目标数据为环结构,包括多个结点,结构体类型定义信息包括数据类型信息和指针信息;相应地,根据目标序列化函数,对目标数据进行序列化处理,得到对应的目标字节流,包括:根据目标序列化函数,对目标数据中的多个结点中各结点进行序列化处理,得到各结点对应的字节流,其中,在生成各结点对应的字节流的过程中,在预设备忘录中记录各结点以及各结点对应的字节流的首地址,使得在再次遇到相同结点的情况下,生成指向结点的首地址的指针。

在一个实施例中,目标字节流包括:数据头、地址标记段和数据段;其中,数据头中包括:版本号、校验码、地址标记段长度以及数据段长度;地址标记段包括目标地址和指针级别,用于表明目标地址中的数据类型为指针级别的指针;数据段中包括目标数据的数据信息。

本申请实施例还提供了一种数据反序列化方法,包括:获取目标代码,其中,目标代码包括用户定义的目标结构体类型定义信息和反序列化函数签名;根据目标代码确定目标结构体类型定义信息和反序列化函数签名;根据目标结构体类型定义信息和反序列化函数签名,生成目标反序列化函数;获取待反序列化的目标字节流,并根据目标反序列化函数对目标字节流进行反序列化处理,得到目标字节流对应的目标数据,其中,目标数据的结构体类型定义信息为目标结构体类型定义信息。

在一个实施例中,目标代码为中间码;相应的,获取目标代码,包括:获取目标源码,其中,目标源码包括预设反序列化函数签名的源码以及目标结构体类型定义信息的源码;对目标源码进行编译,生成中间码。

在一个实施例中,目标结构体类型定义信息包括多个结构体中各结构体的结构体类型定义信息和指针信息;根据反序列化函数签名和结构体类型定义信息生成目标反序列化函数,包括:根据反序列化函数签名和多个结构体中各结构体的结构体类型定义信息和指针信息生成多个结构体中各个结构体的读取函数;根据各个结构体的读取函数,生成目标反序列化函数。

在一个实施例中,根据反序列化函数签名和多个结构体中各结构体的结构体类型定义信息和指针信息生成多个结构体中各个结构体的读取函数,包括:按照以下方式生成多个结构体中当前结构体的读取函数:获取上一个结构体的指针信息,并根据上一个结构体的指针信息确定出当前结构体,其中,多个结构体中的第一个结构体是根据反序列化函数签名的返回类型确定的;根据当前结构体的结构体类型定义信息和指针信息,生成与当前结构体对应的读取函数。

本申请实施例还提供了一种数据序列化装置,包括:获取模块,用于获取目标代码,其中,目标代码包括用户定义的目标数据的结构体类型定义信息和序列化函数签名;确定模块,用于根据目标代码确定序列化函数签名和结构体类型定义信息;生成模块,用于根据序列化函数签名和结构体类型定义信息生成目标序列化函数;处理模块,用于获取待序列化的目标数据,并根据目标序列化函数对目标数据进行序列化处理,得到对应的目标字节流

本申请实施例还提供一种计算机设备,包括处理器以及用于存储处理器可执行指令的存储器,所述处理器执行所述指令时实现上述任意实施例中所述的数据序列化方法的步骤。

本申请实施例还提供一种计算机可读存储介质,其上存储有计算机指令,所述指令被执行时实现上述任意实施例中所述的数据序列化方法的步骤。

在本申请实施例中,提供了一种数据序列化方法,获取包括用户定义的目标数据的结构体类型定义信息和序列化函数签名的目标代码;根据目标代码确定序列化函数签名和结构体类型定义信息;根据序列化函数签名和结构体类型定义信息生成目标序列化函数;获取待序列化的目标数据,并根据目标序列化函数对目标数据进行序列化处理,得到对应的目标字节流。上述方案中,可以由用户定义序列化函数签名和目标数据的结构体类型定义信息,然后根据包括序列化函数签名和结构体类型定义信息的目标代码确定序列化函数签名和目标数据的结构体类型定义信息,并根据序列化函数签名和目标数据的结构体类型定义信息生成目标序列化函数,因而可以针对任意的数据结构类型的目标数据生成目标序列化函数,然后获取目标数据,并根据目标序列化函数对目标数据进行序列化后的目标字节流,从而实现用户定义的任意数据结构类型的目标数据的序列化,而无需将目标数据转换为指定类型的数据结构,简化了数据序列化的过程。

附图说明

此处所说明的附图用来提供对本申请的进一步理解,构成本申请的一部分,并不构成对本申请的限定。在附图中:

图1示出了本申请一实施例中数据序列化方法和数据反序列化方法的应用场景的示意图;

图2示出了本申请一实施例中的数据序列化方法的流程图;

图3示出了本申请一实施例中包括多个结构体的目标数据的结构示意图;

图4示出了本申请一实施例中针对图3中的目标数据的结构类型生成目标序列化函数的示意图;

图5示出了本申请一实施例中结构为环结构的目标数据的结构示意图;

图6示出了本申请一实施例中结构为环结构的目标数据的结构示意图;

图7示出了本申请一实施例中生成的目标字节流的存储格式的示意图;

图8示出了本申请一实施例中生成的目标字节流的存储格式的示意图;

图9示出了本申请一实施例中的数据反序列化方法的流程图;

图10示出了本申请一实施例中的数据序列化装置的示意图;

图11示出了本申请一实施例中的数据反序列化装置的示意图;

图12示出了本申请一实施例中的计算机设备的示意图。

具体实施方式

下面将参考若干示例性实施方式来描述本申请的原理和精神。应当理解,给出这些实施方式仅仅是为了使本领域技术人员能够更好地理解进而实现本申请,而并非以任何方式限制本申请的范围。相反,提供这些实施方式是为了使本申请公开更加透彻和完整,并且能够将本公开的范围完整地传达给本领域的技术人员。

本领域的技术人员知道,本申请的实施方式可以实现为一种系统、装置设备、方法或计算机程序产品。因此,本申请公开可以具体实现为以下形式,即:完全的硬件、完全的软件(包括固件、驻留软件、微代码等),或者硬件和软件结合的形式。

考虑到现有的序列化工具仅能对一种或几种指定的数据结构进行序列化,对于其他数据结构,则需要将其转换为指定的数据结构。这样,一方面需要开发者学习指定的数据结构的使用;另一方面,在应用中必须使用自己定义的结构的情况下,则需要在序列化前把自己定义的结构转换为序列化工具指定的结构,在反序列化后再把序列化工具指定的结构转换为自己定义的结构,过程比较繁琐,此外,如果自己定义的结构中存在私有成员无法访问或设置,则无法转换。

针对上述问题,本申请实施例提供了数据序列化方法和数据反序列化方法。图1示出了本申请一实施例中数据序列化方法和数据反序列化方法的应用场景的示意图。例如,在不同客户端之间传输数据时,需要进行数据序列化和数据反序列化。如图1所示,客户端a希望将目标数据发送至客户端b。客户端a对目标数据进行序列化处理,得到对应的目标字节流。客户端a将序列化得到的目标字节流发送至客户端b。客户端b对目标字节流进行反序列化处理,得到对应的目标数据。上述应用场景仅是示例性的,例如,数据序列化还适用于数据需要存储的场景,需要将内存中分散的数据结构转换为字节流,数据反序列化适用于在存储在磁盘中的数据或者从网络接收的数据需要使用时,将字节流反序列化为数据结构。

图2示出了本申请一实施例中数据序列化方法的流程图。虽然本申请提供了如下述实施例或附图所示的方法操作步骤或装置结构,但基于常规或者无需创造性的劳动在所述方法或装置中可以包括更多或者更少的操作步骤或模块单元。在逻辑性上不存在必要因果关系的步骤或结构中,这些步骤的执行顺序或装置的模块结构不限于本申请实施例描述及附图所示的执行顺序或模块结构。所述的方法或模块结构的在实际中的装置或终端产品应用时,可以按照实施例或者附图所示的方法或模块结构连接进行顺序执行或者并行执行(例如并行处理器或者多线程处理的环境,甚至分布式处理环境)。

具体地,如图2所示,本申请一些实施例提供的数据序列化方法可以包括以下步骤:

步骤s201,获取目标代码。

其中,目标代码包括用户定义的目标数据的结构体类型定义信息和序列化函数签名。其中,序列化函数签名可以包括序列化函数的信息,例如,可以包括函数名、参数类型、参数个数、参数顺序以及参数所在的类和命名空间等信息。目标数据的结构体类型定义信息包括目标数据的各结构体的类型和定义信息。其中,目标数据的数据结构的类型可以包括但不限于:数组、链表、树、堆和散列表等。

步骤s202,根据目标代码确定序列化函数签名和结构体类型定义信息。

步骤s203,根据序列化函数签名和结构体类型定义信息生成目标序列化函数。

在获取目标代码之后,可以根据目标代码确定序列化函数签名和目标数据的结构体类型定义信息。其中,目标数据的结构体类型定义信息可以包括目标数据中的各结构体的定义信息。在确定出序列化函数签名和目标数据的结构体类型定义信息之后,即可以根据序列化函数签名和目标数据的结构体类型定义信息生成目标序列化函数。

步骤s204,获取待序列化的目标数据,并根据目标序列化函数,对目标数据进行序列化处理,得到对应的目标字节流。

在生成目标序列化函数并获取目标数据之后,可以获取待序列化的目标数据,并可以根据目标序列化函数对目标数据进行序列化处理,得到对应的目标字节流。其中,目标数据可以是用户输入的数据结构,也可以是由目标代码生成的数据,还可以是内存中的数据结构,本申请对此不作限制。

上述实施例中的数据序列化方法,可以由用户定义序列化函数签名和目标数据的结构体类型定义信息,然后根据包括序列化函数签名和结构体类型定义信息的目标代码确定序列化函数签名和目标数据的结构体类型定义信息,并根据序列化函数签名和目标数据的结构体类型定义信息生成目标序列化函数,因而可以针对用户定义的任意数据结构类型的目标数据生成目标序列化函数,然后获取目标数据,并根据目标序列化函数对目标数据进行序列化后的目标字节流,从而实现用户定义的任意数据结构类型的目标数据的序列化,而无需将目标数据转换为指定类型的数据结构,简化了数据序列化的过程。

在本申请一些实施例中,目标代码可以包括中间码;相应的,获取目标代码,可以包括:获取目标源码,其中,目标源码包括序列化函数签名的源码以及目标数据的结构体类型定义信息的源码;对目标源码进行编译,生成中间码。

其中,中间码是一种易于翻译成机器码的等效内部表示代码,其介于高级语言代码和机器代码之间。具体地,上述数据序列化方法可以由编译器将目标代码进行编译处理后转换成机器码执行来完成的。目标源码可以为用户先行写出的代码,例如,可以为c语言代码、java代码、c++语言代码等。在获得目标源码之后,为了便于处理,可以对通过编译器前端对目标源码进行编译,生成中间码。其中,中间码的格式可以包括以下之一:llvm(lowlevelvirtualmachine,底层虚拟机)、wasm(webassembly)、jvm(javavirtualmachine,java虚拟机)等。编译器中间层可以根据编译得到的中间码确定序列化函数签名和目标数据的结构体类型定义信息,并根据序列化函数签名和目标数据的结构体类型定义信息生成目标序列化函数,并根据目标序列化函数将中间码中的序列化函数补全,得到补全后的中间码。编译器后端将补全后的中间码转换为机器码。之后,获取目标数据,并调用该机器码对目标数据进行序列化处理。通过上述方式,将目标源码转换为中间码,便于编译器中间层进行分析处理以生成目标序列化函数。

在本申请一些实施例中,目标数据的结构体类型定义信息包括多个结构体中各结构体的结构体类型定义信息和指针信息;根据序列化函数签名和结构体类型定义信息生成目标序列化函数,可以包括:根据序列化函数签名和多个结构体中各结构体的结构体类型定义信息和指针信息生成多个结构体中各个结构体的写入函数;根据各个结构体的写入函数,生成目标序列化函数。

具体地,对于包括多个结构体的目标数据而言,目标数据的结构体类型定义信息包括多个结构体中各结构体的结构体类型定义信息和指针信息。可以根据序列化签名和多个结构体中各结构体的结构体类型定义信息和指针信息生成各结构体的写入函数,然后根据各结构体的写入函数,生成目标序列化函数。其中,写入函数为write函数,可以将结构体中的数据写入二进制字节数据包中。通过上述方式,可以针对包含多个结构体的目标数据生成对应的目标序列化函数。

进一步地,在本申请一些实施例中,根据序列化函数签名和多个结构体中各结构体的结构体类型定义信息和指针信息生成多个结构体中各个结构体的写入函数,可以包括:按照以下方式生成多个结构体中当前结构体的写入函数:获取上一个结构体的指针信息,并根据上一个结构体的指针信息确定出当前结构体,其中,多个结构体中的第一个结构体是根据序列化函数签名中的第一个参数确定的;根据当前结构体的结构体类型定义信息和指针信息,生成与当前结构体对应的写入函数。

在生成第一个结构体对应的写入函数时,根据序列化函数签名中的第一个参数确定第一结构体,并根据第一结构体的结构体类型定义信息和指针信息生成第一个结构体的写入函数。接着,可以根据第一个结构体的指针信息,确定当前结构体,并根据当前结构体的结构体类型定义信息和指针信息,生成与当前结构体对应的写入函数,以此类推,直接生成最后一个结构体对应的写入函数。通过上述方式,可以实现根据序列化函数签名和各结构体的类型定义信息和指针信息生成各结构体对应的写入函数,之后根据写入函数生成目标数据对应的目标序列化函数。

在本申请一些实施例中,该方法还可以包括:在生成多个结构体中各个结构体的写入函数的过程中,在预设的映射表中记录各结构体以及各结构体对应的写入函数。

具体地,考虑到有些情况下,多个结构体为环形结构,为了避免重复写入,可以在生成多个结构体中各结构体的写入函数的过程中,在预设的映射表中记录各结构体以及各结构体对应的写入函数,使得在遇到相同结构体时,避免重复生成写入函数。

请参考图3,图3示出了本申请一实施例中包含多个结构体的目标数据的示意图。具体地,如图3所示,目标数据包括结构体a、b、c、d,其中,结构体a包括两个指针,分别指向结构体b和结构体d,结构体b的指针指向结构体c,结构体c的指针指向结构体a。例如,目标数据的定义和序列化函数签名的目标代码可以如下所示。

structa{

intx;

structb*b;

structd*d;

};

structb{

inty;

structc*c;

};

structc{

intz;

structa*a;

};

structd{

intw;

};

char*packing_a(structa*,unsigned*);

其中,a、b、c、d为目标数据所包含的结构体,char*packing_a(structa*,unsigned*)为序列化函数签名。

请参考图4,图4示出了针对包括a、b、c、d四个结构体的目标数据生成目标序列化函数的示意图。如图4所示,根据目标数据的结构体定义类型信息和序列化函数签名生成目标序列化函数,具体可以包括,从packing_a的第一个参数中得到需要序列化的类型a,从a开始递归地对每个结构体生成一个write函数,在生成的过程中,需要使用映射表记录每个结构体和对应的函数,防止重复生成,生成的目标序列化函数可以如下所示。

其中,write_a、write_b、write_c存在间接递归调用。packing_state是在序列化库里定义的数据类型,其中包含了序列化过程中的信息,可以包括当前处理的状态,空间、内存、映射表。write函数和write_package函数是在序列化库的定义的函数,write_package函数用于处理整体过程,write函数用于防止结构体的重复写入。其中,上面的程序用c语言示例性地示出了生成的目标序列化函数。

在本申请一些实施例中,目标数据为数组。由于不同语言对数组的定义存在差异,因此不同语言的情况下,数组的序列化方法有所不同。对于java这类语言,数组有明确的类型和长度,序列化时只需要先写入数组的长度,再逐个写入数组元素即可。对于c/c++这类语言,无法确定一个指针指向多少个元素,为了解决这个问题,可以定义一个带标记的结构体,把数组长度、数组首地址和标记信息包装起来,以明确数组的定义。

在本申请一些实施例中,目标数据为环结构,可以包括多个结点,结构体类型定义信息包括数据类型信息和指针信息;相应地,根据目标序列化函数,对目标数据进行序列化处理,得到对应的目标字节流,可以包括:根据目标序列化函数,对目标数据中的多个结点中各结点进行序列化处理,得到各结点对应的字节流,其中,在生成各结点对应的字节流的过程中,在预设备忘录中记录各结点以及各结点对应的字节流的首地址,使得在再次遇到相同结点的情况下,生成指向结点的首地址的指针。

示例性地,请参考图5和图6,示意性示出了两种环结构的目标数据。具体地,图5中的第一种环结构(如循环链表)有循环指向,如果不加处理,打包过程(也就是序列化过程)就无法终止。图6中的第二种环结构有重复指向,如果不加处理,结点3会变成两份,解包后得到的数据地址不同,可能会引发错误。对此,根据目标序列化函数,对目标数据中的多个结点中各结点进行序列化处理,得到各结点对应的字节流。并且,在写入各结点的过程中用预设备忘录记录已经写入的结点和它在序列中的下标(即,对应的字节流的首地址),再次遇到相同结点时用一个指针指向它在序列中的下标。通过上述方式,解决了环结构的目标数据序列化过程无法终止以及某些结点重复写入的问题。

在本申请一些实施例中,目标字节流可以包括:数据头、地址标记段和数据段;其中,数据头中包括:版本号、校验码、地址标记段长度以及数据段长度;地址标记段包括目标地址和指针级别,用于表明目标地址中的数据类型为指针级别的指针;数据段中包括目标数据的数据信息。

具体地,根据本申请实施例中提供的数据序列化方法对目标进行序列化后生成的目标字节流的存储格式可以包括三段:数据头、地址标记段和数据段。其中,数据头中存储有版本号、校验码、地址标记段长度以及数据段长度。地址标记段包括目标地址和指针级别,用于表明目标地址中的数据类型为该指针级别的指针。数据段中存储有目标数据的数据信息。

请参考图7和图8,分别示出了两种目标数据序列化后生成的目标字节流的存储格式的示意图。如图7所示,以循环链表为例,(1,2,3,4,5,6)是一个循环链表,结点6的next指针指向结点1,它序列化后得到的目标字节流的数据包结构如图7所示。在图7中,地址标记段只有一个元素,用于标记地址为28的数据是一个1级指针。如图8所示,对于链表(1)、(2)、(3),每个链表都只有一个结点,next指针指向相同的地址null,则在地址标记段用一个3级指针指向结点3的next域,结点3的next域指向之前指向null的域。

在本申请一些实施例中,根据从编译器接口中得到的语言类型、目标数据的结构体类型定义信息和序列化函数签名,可以生成另一种语言的目标序列化函数,从而实现跨语言通信。

在本申请一些实施例中,可以将目标数据的结构体类型定义信息序列化。对于不同的源代码、中间码,相同的结构体类型定义信息会有不同的表示方法,通过遍历类型定义信息,可以生成一份统一格式的结构体类型定义信息表示方法。例如,可以用自举的方法将结构体类型定义信息序列化,得到一份内存上连续的结构体类型定义信息。这份连续的结构体类型定义信息有以下两个用途:1、校验:用于计算结构体类型定义信息的散列值,分别存在数据头和反序列化函数中,可以在解包(反序列化)前校验包的数据类型与反序列化解包的数据类型是否一致;2、跨语言代码生成:用于将序列化后的结构体类型定义信息传给另一种语言写的代码生成工具,可以用它生成这个语言的代码,实现跨语言通信。

本申请实施例还提供了一种数据反序列化方法。具体地,如图9所示,本申请一些实施例提供的数据反序列化方法可以包括以下步骤:

步骤s901,获取目标代码,其中,目标代码包括用户定义的目标结构体类型定义信息和反序列化函数签名。

具体地,目标代码包括用户定义的目标数据的结构体类型定义信息和反序列化函数签名。其中,反序列化函数签名可以包括反序列化函数的信息,例如,可以包括函数名、参数类型、参数个数、参数顺序以及参数所在的类和命名空间等信息。目标结构体类型定义信息包括各结构体的类型和定义信息。其中,目标数据的数据结构的类型可以包括但不限于:数组、链表、树、堆和散列表等。

步骤s902,根据目标代码确定目标结构体类型定义信息和反序列化函数签名。

步骤s903,根据目标结构体类型定义信息和反序列化函数签名,生成目标反序列化函数。

在获取目标代码之后,可以根据目标代码确定反序列化函数签名和目标结构体类型定义信息。其中,目标结构体类型定义信息可以包括最终生成的目标数据中的各结构体的定义信息。在确定出反序列化函数签名和目标结构体类型定义信息之后,即可以根据反序列化函数签名和目标结构体类型定义信息生成目标反序列化函数。

步骤s904,获取待反序列化的目标字节流,并根据目标反序列化函数对目标字节流进行反序列化处理,得到目标字节流对应的目标数据,其中,目标数据的结构体类型定义信息为目标结构体类型定义信息。

在生成目标反序列化函数并获取目标数据之后,可以获取待反序列化的目标字节流,并可以根据目标反序列化函数对目标字节流进行反序列化处理,得到目标字节流对应的目标数据。其中,目标字节流可以是从网络获取的字节流,也可以是从磁盘读取的字节流,本申请对此不做限制。其中,反序列化后得到的目标数据的结构体类型定义信息为目标结构体类型定义信息。

上述方案中,可以由用户定义反序列化函数签名并给出反序列化后生成的目标数据的目标结构体类型定义信息,然后根据包括反序列化函数签名和目标结构体类型定义信息的目标代码确定反序列化函数签名和目标结构体类型定义信息,并根据反序列化函数签名和目标结构体类型定义信息生成目标反序列化函数,因而可以得到针对目标字节流生成用户定义的任意目标数据结构类型的目标数据的目标反序列化函数,然后获取目标字节流,并根据目标反序列化函数对目标字节流进行反序列化处理后,得到对应的目标数据,从而实现目标字节流反序列化成用户定义的任意数据结构类型的目标数据,而无需将反序列化后得到的指定类型数据转换为目标结构体类型的目标数据,简化了数据反序列化的过程。

在本申请一些实施例中,目标代码为中间码;相应的,获取目标代码,包括:获取目标源码,其中,目标源码包括预设反序列化函数签名的源码以及目标结构体类型定义信息的源码;对目标源码进行编译,生成中间码。

具体地,上述数据反序列化方法可以由编译器将目标代码进行编译处理后转换成机器码执行来完成的。目标源码可以为用户先行写出的代码,例如,可以为c语言代码、java代码、c++语言代码等。在获得目标源码之后,为了便于处理,可以对通过编译器前端对目标源码进行编译,生成中间码。其中,中间码的格式可以包括以下之一:llvm(lowlevelvirtualmachine,底层虚拟机)、wasm(webassembly)、jvm(javavirtualmachine,java虚拟机)等。编译器中间层可以根据编译得到的中间码确定反序列化函数签名和目标结构体类型定义信息,并根据反序列化函数签名和目标结构体类型定义信息生成目标反序列化函数,并根据目标反序列化函数将中间码中的反序列化函数补全,得到补全后的中间码。编译器后端将补全后的中间码转换为机器码。之后,获取目标字节流,并调用该机器码即可以进行目标字节流的反序列化处理。通过上述方式,将目标源码转换为中间码,便于编译器中间层进行分析处理以生成目标反序列化函数。

在本申请一些实施例中,目标结构体类型定义信息包括多个结构体中各结构体的结构体类型定义信息和指针信息;根据反序列化函数签名和结构体类型定义信息生成目标反序列化函数,包括:根据反序列化函数签名和多个结构体中各结构体的结构体类型定义信息和指针信息生成多个结构体中各个结构体的读取函数;根据各个结构体的读取函数,生成目标反序列化函数。

具体地,对于包括多个结构体的目标数据而言,目标结构体类型定义信息包括多个结构体中各结构体的结构体类型定义信息和指针信息。可以根据反序列化签名和多个结构体中各结构体的结构体类型定义信息和指针信息生成各结构体的读取函数,然后根据各结构体的读取函数,生成目标反序列化函数。其中,读取函数为read函数,可以将二进制字节数据包中的数据转换为目标结构体类型定义信息中定义的目标数据。通过上述方式,可以针对要转换成包含多个结构体的目标数据的目标字节流生成对应的目标反序列化函数。

在生成第一个结构体对应的写入函数时,根据反序列化函数签名的返回类型确定第一结构体,并根据第一结构体的结构体类型定义信息和指针信息生成第一个结构体的读取函数。接着,可以根据第一个结构体的指针信息,确定当前结构体,并根据当前结构体的结构体类型定义信息和指针信息,生成与当前结构体对应的读取函数,以此类推,直接生成最后一个结构体对应的读取函数。通过上述方式,可以实现根据反序列化函数签名和各结构体的类型定义信息和指针信息生成各结构体对应的读取函数,之后根据读取函数生成目标字节流对应的目标反序列化函数。

在本申请一些实施例中,根据反序列化函数签名和多个结构体中各结构体的结构体类型定义信息和指针信息生成多个结构体中各个结构体的读取函数,包括:按照以下方式生成多个结构体中当前结构体的读取函数:获取上一个结构体的指针信息,并根据上一个结构体的指针信息确定出当前结构体,其中,多个结构体中的第一个结构体是根据反序列化函数签名的返回类型确定的;根据当前结构体的结构体类型定义信息和指针信息,生成与当前结构体对应的读取函数。

在本申请一些实施例中,该方法还可以包括:在生成多个结构体中各个结构体的读取函数的过程中,在预设的映射表中记录各结构体以及各结构体对应的读取函数。

具体地,考虑到有些情况下,多个结构体为环形结构,为了避免重复读取,可以在生成多个结构体中各结构体的读取函数的过程中,在预设的映射表中记录各结构体以及各结构体对应的读取函数,使得在遇到相同结构体时,避免重复生成读取函数,从而避免结构体重复读取。

请参考图3,图3示出了本申请一实施例中包含多个结构体的目标数据的示意图。具体地,如图3所示,目标数据包括结构体a、b、c、d,其中,结构体a包括两个指针,分别指向结构体b和结构体d,结构体b的指针指向结构体c,结构体c的指针指向结构体a。例如,目标结构体类型定义信息和反序列化函数签名的目标代码可以如下所示。

structa{

intx;

structb*b;

structd*d;

};

structb{

inty;

structc*c;

};

structc{

intz;

structa*a;

};

structd{

intw;

};

structa*unpacking_a(char*);

其中,a、b、c、d为目标数据所包含的结构体,structa*unpacking_a(char*)为反序列化函数签名。

对于上述目标结构体类型定义信息,根据目标结构体定义类型信息和反序列化函数签名生成目标反序列化函数,具体可以包括,从unpacking_a的返回类型得到需要反序列化的类型a,从a开始递归地对每个结构体生成一个read函数,在生成的过程中,需要使用映射表记录每个结构体和对应的函数,防止重复生成,生成的目标反序列化函数如下所示。

其中,read_a、read_b、read_c存在间接递归调用。unpacking_state是在序列化库里定义的数据类型,其中包含了反序列化过程中的信息。read和read_package是在序列化库的定义的函数,read_package用于处理整体反序列化过程,read用于防止结构体的重复分配。其中,上面的程序用c语言示例性地示出了生成的目标反序列化函数。可以理解的是,生成的目标反序列化函数可以是除了c语言之外的其他语言的格式,也可以是中间码格式,本申请对此不作限制。

在本申请一些实施例中,目标字节流可以包括:数据头、地址标记段和数据段;其中,数据头中包括:版本号、校验码、地址标记段长度以及数据段长度;地址标记段包括目标地址和指针级别,用于表明目标地址中的数据类型为指针级别的指针;数据段中包括目标数据的数据信息。

具体地,目标字节流的存储格式可以包括三段:数据头、地址标记段和数据段。其中,数据头中存储有版本号、校验码、地址标记段长度以及数据段长度。地址标记段包括目标地址和指针级别,用于表明目标地址中的数据类型为该指针级别的指针。数据段中存储有目标数据的数据信息。

在本申请一些实施例中,根据从编译器接口中得到的语言类型、目标结构体类型定义信息和反序列化函数签名,可以生成另一种语言的反序列化代码,从而实现跨语言通信。

基于同一发明构思,本申请实施例中还提供了一种数据序列化装置,如下面的实施例所述。由于数据序列化装置解决问题的原理与数据序列化方法相似,因此数据序列化装置的实施可以参见数据序列化方法的实施,重复之处不再赘述。以下所使用的,术语“单元”或者“模块”可以实现预定功能的软件和/或硬件的组合。尽管以下实施例所描述的装置较佳地以软件来实现,但是硬件,或者软件和硬件的组合的实现也是可能并被构想的。图10是本申请实施例的数据序列化装置的一种结构框图,如图10所示,包括:获取模块1001、确定模块1002、生成模块1003和处理模块1004,下面对该结构进行说明。

获取模块1001用于获取目标代码,其中,目标代码包括用户定义的目标数据的结构体类型定义信息和序列化函数签名。

确定模块1002用于根据目标代码确定序列化函数签名和结构体类型定义信息。

生成模块1003用于根据序列化函数签名和结构体类型定义信息生成目标序列化函数。

处理模块1004用于获取待序列化的目标数据,并根据目标序列化函数对目标数据进行序列化处理,得到对应的目标字节流。

在本申请一些实施例中,目标代码包括中间码;相应的,获取模块可以具体用于:获取目标源码,其中,目标源码包括序列化函数签名的源码以及目标数据的结构体类型定义信息的源码;对目标源码进行编译,生成中间码。

在本申请一些实施例中,目标数据的结构体类型定义信息包括多个结构体中各结构体的结构体类型定义信息和指针信息;生成模块可以具体用于:根据序列化函数签名和多个结构体中各结构体的结构体类型定义信息和指针信息生成多个结构体中各个结构体的写入函数;根据各个结构体的写入函数,生成目标序列化函数。

在本申请一些实施例中,根据序列化函数签名和多个结构体中各结构体的结构体类型定义信息和指针信息生成多个结构体中各个结构体的写入函数,包括:按照以下方式生成多个结构体中当前结构体的写入函数:获取上一个结构体的指针信息,并根据上一个结构体的指针信息确定出当前结构体,其中,多个结构体中的第一个结构体是根据序列化函数签名中的第一个参数确定的;根据当前结构体的结构体类型定义信息和指针信息,生成与当前结构体对应的写入函数。

在本申请一些实施例中,该装置还包括记录模块,记录模块可以具体用于:在生成模块生成多个结构体中各个结构体的写入函数的过程中,在预设的映射表中记录各结构体以及各结构体对应的写入函数。

在本申请一些实施例中,目标数据为环结构,可以包括多个结点,结构体类型定义信息包括数据类型信息和指针信息;相应地,处理模块可以具体用于:根据目标序列化函数,对目标数据中的多个结点中各结点进行序列化处理,得到各结点对应的字节流,其中,在生成各结点对应的字节流的过程中,在预设备忘录中记录各结点以及各结点对应的字节流的首地址,使得在再次遇到相同结点的情况下,生成指向结点的首地址的指针。

在本申请一些实施例中,目标字节流可以包括:数据头、地址标记段和数据段;其中,数据头中包括:版本号、校验码、地址标记段长度以及数据段长度;地址标记段包括目标地址和指针级别,用于表明目标地址中的数据类型为指针级别的指针;数据段中包括目标数据的数据信息。

基于同一发明构思,本申请实施例中还提供了一种数据反序列化装置,如下面的实施例所述。由于数据反序列化装置解决问题的原理与数据反序列化方法相似,因此数据反序列化装置的实施可以参见数据反序列化方法的实施,重复之处不再赘述。以下所使用的,术语“单元”或者“模块”可以实现预定功能的软件和/或硬件的组合。尽管以下实施例所描述的装置较佳地以软件来实现,但是硬件,或者软件和硬件的组合的实现也是可能并被构想的。图11是本申请实施例的数据反序列化装置的一种结构框图,如图11所示,包括:获取模块1101、确定模块1102、生成模块1103和处理模块1104,下面对该结构进行说明。

获取模块1101用于获取目标代码,其中,目标代码包括用户定义的目标结构体类型定义信息和反序列化函数签名。

确定模块1102用于根据目标代码确定目标结构体类型定义信息和反序列化函数签名。

生成模块1103用于根据目标结构体类型定义信息和反序列化函数签名,生成目标反序列化函数。

处理模块1104用于获取待反序列化的目标字节流,并根据目标反序列化函数对目标字节流进行反序列化处理,得到目标字节流对应的目标数据,其中,目标数据的结构体类型定义信息为目标结构体类型定义信息。

在本申请一些实施例中,目标代码为中间码;相应的,获取模块可以具体用于:获取目标源码,其中,目标源码包括预设反序列化函数签名的源码以及目标结构体类型定义信息的源码;对目标源码进行编译,生成中间码。

在本申请一些实施例中,目标结构体类型定义信息包括多个结构体中各结构体的结构体类型定义信息和指针信息;生成模块可以具体用于:根据反序列化函数签名和多个结构体中各结构体的结构体类型定义信息和指针信息生成多个结构体中各个结构体的读取函数;根据各个结构体的读取函数,生成目标反序列化函数。

在本申请一些实施例中,根据反序列化函数签名和多个结构体中各结构体的结构体类型定义信息和指针信息生成多个结构体中各个结构体的读取函数,包括:按照以下方式生成多个结构体中当前结构体的读取函数:获取上一个结构体的指针信息,并根据上一个结构体的指针信息确定出当前结构体,其中,多个结构体中的第一个结构体是根据反序列化函数签名的返回类型确定的;根据当前结构体的结构体类型定义信息和指针信息,生成与当前结构体对应的读取函数。

从以上的描述中,可以看出,本申请实施例实现了如下技术效果:可以由用户定义序列化函数签名和目标数据的结构体类型定义信息,然后根据包括序列化函数签名和结构体类型定义信息的目标代码确定序列化函数签名和目标数据的结构体类型定义信息,并根据序列化函数签名和目标数据的结构体类型定义信息生成目标序列化函数,因而可以针对任意的数据结构类型的目标数据生成目标序列化函数,然后获取目标数据并根据目标序列化函数对目标数据进行序列化处理,生成对应的目标字节流,从而实现用户定义的任意数据结构类型的目标数据的序列化,而无需将目标数据转换为指定类型的数据结构,简化了数据序列化的过程。

本申请实施方式还提供了一种计算机设备,具体可以参阅图12所示的基于本申请实施例提供的数据序列化方法或数据反序列化方法的计算机设备组成结构示意图,所述计算机设备具体可以包括输入设备121、处理器122、存储器123。其中,所述存储器123用于存储处理器可执行指令。所述处理器122执行所述指令时实现上述任意实施例中所述的数据序列化方法或数据反序列化方法的步骤。

在本实施方式中,所述输入设备具体可以是用户和计算机系统之间进行信息交换的主要装置之一。所述输入设备可以包括键盘、鼠标、摄像头、扫描仪、光笔、手写输入板、语音输入装置等;输入设备用于把原始数据和处理这些数的程序输入到计算机中。所述输入设备还可以获取接收其他模块、单元、设备传输过来的数据。所述处理器可以按任何适当的方式实现。例如,处理器可以采取例如微处理器或处理器以及存储可由该(微)处理器执行的计算机可读程序代码(例如软件或固件)的计算机可读介质、逻辑门、开关、专用集成电路(applicationspecificintegratedcircuit,asic)、可编程逻辑控制器和嵌入微控制器的形式等等。所述存储器具体可以是现代信息技术中用于保存信息的记忆设备。所述存储器可以包括多个层次,在数字系统中,只要能保存二进制数据的都可以是存储器;在集成电路中,一个没有实物形式的具有存储功能的电路也叫存储器,如ram、fifo等;在系统中,具有实物形式的存储设备也叫存储器,如内存条、tf卡等。

在本实施方式中,该计算机设备具体实现的功能和效果,可以与其它实施方式对照解释,在此不再赘述。

本申请实施方式中还提供了一种基于数据序列化方法或数据反序列化方法的计算机存储介质,所述计算机存储介质存储有计算机程序指令,在所述计算机程序指令被执行时实现上述任意实施例中所述数据序列化方法或数据反序列化方法的步骤。

在本实施方式中,上述存储介质包括但不限于随机存取存储器(randomaccessmemory,ram)、只读存储器(read-onlymemory,rom)、缓存(cache)、硬盘(harddiskdrive,hdd)或者存储卡(memorycard)。所述存储器可以用于存储计算机程序指令。网络通信单元可以是依照通信协议规定的标准设置的,用于进行网络连接通信的接口。

在本实施方式中,该计算机存储介质存储的程序指令具体实现的功能和效果,可以与其它实施方式对照解释,在此不再赘述。

显然,本领域的技术人员应该明白,上述的本申请实施例的各模块或各步骤可以用通用的计算装置来实现,它们可以集中在单个的计算装置上,或者分布在多个计算装置所组成的网络上,可选地,它们可以用计算装置可执行的程序代码来实现,从而,可以将它们存储在存储装置中由计算装置来执行,并且在某些情况下,可以以不同于此处的顺序执行所示出或描述的步骤,或者将它们分别制作成各个集成电路模块,或者将它们中的多个模块或步骤制作成单个集成电路模块来实现。这样,本申请实施例不限制于任何特定的硬件和软件结合。

应该理解,以上描述是为了进行图示说明而不是为了进行限制。通过阅读上述描述,在所提供的示例之外的许多实施方式和许多应用对本领域技术人员来说都将是显而易见的。因此,本申请的范围不应该参照上述描述来确定,而是应该参照前述权利要求以及这些权利要求所拥有的等价物的全部范围来确定。

以上所述仅为本申请的优选实施例而已,并不用于限制本申请,对于本领域的技术人员来说,本申请实施例可以有各种更改和变化。凡在本申请的精神和原则之内,所作的任何修改、等同替换、改进等,均应包含在本申请的保护范围之内。

当前第1页1 2 
网友询问留言 已有0条留言
  • 还没有人留言评论。精彩留言会获得点赞!
1