PS:个人理解,如有错误,敬请指正。
首发地址:
从 GetDerivedClasses 所需数据来源来剖析 UE4 的反射原理和运行机制
摘要
UE4 有提供很多反射接口,来获取各种反射数据,如 UObjectHash 类的 GetDerivedClasses。本文以这个接口为例,分析这个接口使用的数据的来源,说明 UE4 的反射原理和实现机制。或者说,从 UCLASS 、GENERATED_BODY 等宏到 GetDerivedClasses 所需的反射数据子类列表( ClassToChildListMap )
概述
UE4 通过 UCLASS 和 GENERATED_BODY 等宏来标记类型和成员,编译时通过 UHT 根据这些宏来自动生成反射数据代码,运行时基于 Static 语法自动注册和收集各类型的信息,最后添加到各种容器中,以待使用。
详细说明
编码期,宏标记
我们在 UE4 中创建各种类型后,会在其中使用各种需要的宏来标记各类型和成员,如 UCLASS、GENERATED_BODY、UPROPERTY、UFUNTION 等。
编译期,代码生成
- UE4 启动编译时,会先运行 UHT 再执行真正编译。
UnrealHeaderTool (UHT)是一个支持 UObject 系统的自定义解析和代码生成工具。代码编译分两个阶段进行:
- 调用 UHT,它解析 C++ 标头以获取与 Unreal 相关的类元数据,并生成自定义代码以实现各种与 UObject 相关的功能。
- 调用普通 C++ 编译器来编译结果。
UnrealHeaderTool
2. UHT 会处理所有头文件,分析其中的 UCLASS、GENERATED_BODY、UPROPERTY、UFUNTION 等宏,生成对应类型的 *.generate.h 和 *.generate.cpp。
*. 生成的文件的路径:YourProjectName\Intermediate\Build\Win64\UE4Editor\Inc\YourProjectName。
- 具体来说,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
- 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,转载请附上原文链接及本声明。