UE4.27, 揣摩源码, 序列化 (三) FLinkerLoad, FLinkerSave

news/2025/1/1 17:26:41/文章来源:https://www.cnblogs.com/chenxuanzuo/p/18633621

3.  FLinkerLoad, FLinkerSave分别是UObject的反序列化和序列化的内核

  3.0. UPackage与UObject

    UObject因为涉及与其他UObject的复杂引用关系,如果我们客制化地单独正反序列化每一个UObject,我们会在反序列化的时候惊觉这是繁琐而不可能的。

    为了满足UObject这种复杂的对象的序列化,UE选择将UObject和一大批额外信息整合为UPackage,
    以正反序列化UPackage的方式,将UObject连带着这堆信息一齐正反序列化

 

  3.1. SVO

    UObject序列化:获得与该UObject有外部链关系的UPackage后,FLinker凭借合法的UPackage创建FLinkerSave,并序列化UPackage

    UObject反序列化:获得UPackage后,FLinker凭借合法的UPackage创建FLinkerLoad,并籍此反序列化UPackage

      UObject反序列化相当复杂,SVO的说明只能引领整体思考

 

 

    实际观察的反序列化堆栈后,我们会发现:

    LoadObject()->StaticLoadObject()

    LoadClass()->StaticLoadObject()

    ->StaticLoadObject()->StaticLoadObjectInternal  ->ResolveName

                           -尝试使用传入的字符串来获得upackage,并处理出ObjectName-

                           [ResolveName成功,获得upackage]->StaitcFindObjectFast

                                             ->StaticFindObjectFastInternal

                                             -全局UObject哈希表查找-

                           [ResolveName失败]->[字符串可疑(没有‘.’) ]-> -修补字符串- ->StaticFindObjectFastInternal
                                                      -全局UObject哈希表查找-

 

  3.2. 关键继承关系

    FLinkerLoadFLinkerSave
      class FLinkerLoad : public FLinker, public FArchiveUObject

      class FLinkerSave : public FLinker, public FArchiveUObject

        class FLinker : public FLinkerTables

 

    FArchiveUObject

      class FArchiveUObject : public FArchive

        class FArchive : private FArchiveState

  3.3. 类层级与基本功能说明
    3.3.1. FArchiveUObject

      其中四个静态函数和<<运算符重载,本质上负责了序列化FLazyObjectPtr, FSoftObjectPtr, FSoftObjectPath, FWeakObjectPtr四个特殊的UObjectPtr类型

      其中的实现相当简单,在特殊条件下序列化对应object的guid,正常情况下序列化UObject*
    3.3.2. FLinkerTables

      还记得前文提到的UPackage的组成结构吗?Summary, Names, Imports Table, Exports Table, Depends Table, ImportGuids Map, ExportGuids Map, Thumbnails, Export-Objects

      FLinkerTables结构体里直接定义了 Names, Imports Table, Exports Table, Depends Table,显然它是反序列化时存储uobject的其他相关数据的重要结构体

    3.3.3. FLinker

      UE注释里是这样介绍FLinker的,管理与ue相关的package数据,充当磁盘内容内存中的UPackage桥梁

 

      Manages the data associated with an Unreal package. Acts as the bridge betweenthe file on disk and the UPackage object in memory for all Unreal package types.
      从这一段话可能难以注意到的信息,事实上FLinker在作用前总是需要磁盘内容和内存中的UPackage同时有效,正如桥梁不能悬空作用,它需要桥墩的两端都有效

      FLinker里定义了 Summary

    3.3.4. FLinkerLoad 

      FLinkerLoad的Tick函数将各种UPackage的除ExportObject数据从uasset中加载进来

      最后调用LoadAllObjects彻底完成反序列化
    3.3.5. FLinkerSave

      原谅我能力有限,以下内容不一定准确

      FLinkerSave在package.h的静态函数Save里的应用,比如接受该类基类archive的serialize函数是重写在各个客制化的UObject派生类里的,

      更贴近的应用,反而更多是使用linker的tell和seek作为工具类,或者使用其中的结构体来存储逻辑标识而不是实际写入的数据来作为辅助类
      真正写入二进制数据的函数是这个SavePackageUtilities::WriteToFile

    3.3.6. Thumbnails 在FLinkerManager::EnsureLoadingComplete被加载

 

  3.4. 调用堆栈

    3.4.1 UObject序列化

      UPackage::SavePackage()->

        UPackage::Save()->

          ->2711-2862 序列化CDO或者依靠子类的重写serialize函数序列化子类

          //在此处查找这个serialize的引用,很多子类,某某actor都重写了它

           -2899-3023 标记相关object,class,package的名称


             -// Build ImportMap.

          -// Build ExportMap.

 

          -...

          // Save the import map.

          // Save the export map.
          -...

          -finished


    3.4.2 UObject反序列化

      LoadObject()->

        StaticLoadObject()->

          StaticLoadObjectInternal()->

            ResolveName()//由StrName(其实是传入的路径TChar*参数)查找UPackage,找不到会创建一个

              LoadPackage()

            StaticFindObjectFast()

              StaticFindObjectFastInternal()

                StaticFindObjectFastInternalThreadSafe()

                  //使用全局UObject的哈希表查询

            //...杂七杂八的路径修补后重新尝试

 

      LoadPackage()是实际的反序列化步骤

      LoadPackage()->

        LoadPackageInternal()->

          //...//寻找package

          GetPackageLinker()->

          //寻找或者创建一个FLinkerLoad* Linker

            FLinkerLoad::CreateLinker()->

              Tick()

              //一系列反序列化在此完成

            Linker->LoadAllObjects()

            // 加载UObejcts

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/861026.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

设计Element UI表单组件居然如此简单!

0 前言 上文讲解了Jest框架对组件库测试,TypeScript和Jest都为代码质量和研发效率。之前实现Container和Button组件以渲染功能为主,可根据不同属性渲染不同样式去实现布局和不同格式的按钮。 本文的表单组件,除了要渲染页面组件,还支持很好页面交互,从Element3的表单组件开…

Kubernetes(v1.29)学习笔记

什么是KubernetesK8s是Kubernetes的简称,是一个开源的容器编排系统,用于自动部署、扩展和管理容器化应用程序。 Kubernetes源于希腊语,意为“舵手”或“飞行员”,其主要功能包括服务发现与负载均衡、存储编排、Secret和配置管理、批量执行、水平扩缩、自动化上线和回滚、自…

简答题

1 冯诺依曼结构计算机的基本思想是什么 ?按此思想设计的计算机硬件系统的应由那些部件组成,它们各有什么作用? 存储程序和程序控制是冯诺依曼结构计算机的主要设计思想。存储程序是指将解题的步骤编写为程序,然后将程序和运行程序所需要的数据以二进制的形式存放到存储器中…

基于双PI控制器和三电平SVPWM交流同步直线电机矢量控制系统的simulink建模与仿真

1.课题概述基于PSO粒子群优化的PV光伏发电系统simulink建模与仿真。通过PSO粒子群优化进行最大功率跟踪。2.系统仿真结果 3.核心程序与模型 版本:MATLAB2022a 4.系统原理简介光伏(Photovoltaic, PV)发电系统利用太阳能直接转换成电能,是实现可持续能源战略的重要组成部分。…

Gridview使用CheckBox全选与单选 Version 3

还是有网友开发ASP.NET程序,今天联系Insus.NET说,参考下面随笔,无法实现,没有效果。Gridview使用CheckBox全选与单选 Version 2 https://www.cnblogs.com/insus/archive/2013/05/22/3093114.html 几番仔细检查,放大对着搬,照抄,没能错呀!说实的,具体原因,Insus.NET…

RL中on-policy和off-policy的本质区别/重要性采样

讨论了on-policy和off-policy的本质区别。说明了off-policy MC和off-policy TD是如何利用重要性采样的,以及为什么Q-learning不需要进行重要性采样。本随笔的图片都来自UCL强化学习课程lec5 Model-free prediction的ppt (Teaching - David Silver ). 回忆值函数的表达式: \[v…

2024-2025-1 20241319 《计算机基础与程序设计》第十四周学习总结

作业信息这个作业属于哪个课程 2024-2025-1-计算机基础与程序设计这个作业要求在哪里 https://www.cnblogs.com/rocedu/p/9577842.html#WEEK14这个作业的目标 《C语言程序设计》第13章作业正文 https://www.cnblogs.com/wchxx/p/18639513**教材学习内容总结 1. 文件的打开与关闭…

视野修炼-技术周刊第115期 | 现代的 Nodejs 能力

① 一些现代的 Nodejs 能力 ② MarkItDown ③ ReactAI ④ 背景移除 ⑤ 智能图片描述生成器生成器欢迎来到第 115 期的【视野修炼 - 技术周刊】,下面是本期的精选内容简介 🔥强烈推荐一些现代的 Nodejs 能力🔧开源工具&技术资讯MarkItDown ReactAI🤖AI工具&资讯背…

2024-2025-1(20241321)《计算机基础与程序设计》第十四周学习总结

这个作业属于哪个课程 <班级的链接>(2024-2025-1-计算机基础与程序设计)这个作业要求在哪里 <作业要求的链接>(2024-2025-1计算机基础与程序设计第十四周作业)这个作业的目标 <深刻学习C语言,反思一周学习,温故知新>作业正文 ... 本博客链接https://www.…

11. 日期和时间控件

一、日期和时间控件日期和时间类也是 PySide6 中的基本类,利用它们可以设置纪年法、记录某个日期时间点、对日期时间进行计算等。用户输入日期时间及显示日期时间时需要用到日期时间控件,本节介绍有关日期时间的类及相关控件。我们可以在终端中使用 pip 安装 pyside6 模块。 …

浅析FHQ-treap

前言 更好的阅读体验 默认读者会 BST 的基本操作。 节点定义 替罪羊树采用了懒惰删除的方法,不会立即删除某个点,而是在重构时不放进数组。 struct node{ int ch[2], val; int siz1, siz2, cnt, sum; //扣去懒惰删除的节点数量,没扣去懒惰删除的节点数量,树内相同权值的…

20241313刘鸣宇《计算机基础与程序设计》第14周学习总结

2024-2025-1 20241313《计算机基础与程序设计》第14周学习总结 作业信息这个作业属于哪个课程 <班级的链接>(如2024-2025-1-计算机基础与程序设计)这个作业要求在哪里 <作业要求的链接>(如2024-2025-1计算机基础与程序设计第一周作业)这个作业的目标 <写上具…