从 GetDerivedClasses 所需数据来源来剖析 UE4 的反射原理和运行机制

Viewed 28

PS:个人理解,如有错误,敬请指正。

首发地址:

从 GetDerivedClasses 所需数据来源来剖析 UE4 的反射原理和运行机制

摘要

UE4 有提供很多反射接口,来获取各种反射数据,如 UObjectHash 类的 GetDerivedClasses。本文以这个接口为例,分析这个接口使用的数据的来源,说明 UE4 的反射原理和实现机制。或者说,从 UCLASS 、GENERATED_BODY 等宏到 GetDerivedClasses 所需的反射数据子类列表( ClassToChildListMap )

概述

UE4 通过 UCLASS 和 GENERATED_BODY 等宏来标记类型和成员,编译时通过 UHT 根据这些宏来自动生成反射数据代码,运行时基于 Static 语法自动注册和收集各类型的信息,最后添加到各种容器中,以待使用。

详细说明

编码期,宏标记

我们在 UE4 中创建各种类型后,会在其中使用各种需要的宏来标记各类型和成员,如 UCLASS、GENERATED_BODY、UPROPERTY、UFUNTION 等。

编译期,代码生成

  1. UE4 启动编译时,会先运行 UHT 再执行真正编译。

UnrealHeaderTool (UHT)是一个支持 UObject 系统的自定义解析和代码生成工具。代码编译分两个阶段进行:

  1. 调用 UHT,它解析 C++ 标头以获取与 Unreal 相关的类元数据,并生成自定义代码以实现各种与 UObject 相关的功能。
  2. 调用普通 C++ 编译器来编译结果。

UnrealHeaderTool
2. UHT 会处理所有头文件,分析其中的 UCLASS、GENERATED_BODY、UPROPERTY、UFUNTION 等宏,生成对应类型的 *.generate.h 和 *.generate.cpp。
*. 生成的文件的路径:YourProjectName\Intermediate\Build\Win64\UE4Editor\Inc\YourProjectName。

  1. 具体来说,UHT 调用 CodeGenerator.cpp 生成 *.generated.h 和 *.gen.cpp ,其根据类和属性、方法等的各种 ClassFlags 、MetaData 等标签生成各种宏和模板代码,如 DECLARE_CLASS 和 IMPLEMENT_CLASS 。
    *. CodeGenerator.cpp 中的 DECLARE_CLASS 和 IMPLEMENT_CLASS 等

*. *generated.h 中的 DECLARE_CLASS

*. *.gen.cpp 中的 IMPLEMENT_CLASS

  1. DECLARE_CLASS 中定义有 StaticClass ,各种 IMPLEMENT_CLASS 中定义有 GetPrivateStaticClass,StaticClass 会调用 GetPrivateStaticClass ,GetPrivateStaticClass 又会调用 GetPrivateStaticClassBody 。
    *. 如图,见 ObjectMacros.h

运行时,注册和收集

  • 各类型生成的代码中,有 StaticClass 这个 Static 方法,其语法特性决定其会在程序启动时自动执行。其最终会把各种类中的各种属性方法等数据自动注册和收集起来,并放到各容器中管理起来,以便后续调用。
  • 详细的流程见反射数据收集和注册的时序图(以 ClassToObjectListMap 的角度)

运行时,使用

  • 这样,我们在需要的时候就可以从各反射数据容器中找到想要的数据了
  • 如 GetDerivedClasses 通过 ThreadHash.ClassToChildListMap.Find 找到继承自某类的所有子类。

总结,流程图

整个反射机制流程可以用如下所示流程图来简要概括

参考链接

UE4反射原理的探究
Unreal Property System (Reflection)
虚幻4属性系统(反射)翻译
深入研究虚幻4反射系统实现原理(一)
深入研究虚幻4反射系统实现原理(二)
深入研究虚幻4反射系统实现原理(三)
UE4反射系统简析(含实例过程分析)

**声明:**本文来自公众号:GameDevLearning,转载请附上原文链接及本声明。

0 Answers