2.1 UE4反射分析-空AActor拆解

Ophelia ·
更新时间:2024-09-21
· 797 次阅读

一、创建一个继承自AActor的空类AMyActor,对GENERATED_BODY()宏Alt+G不断深入(需安装Visual Assist) 二、展开GENERATED_BODY() 2.1、第一次展开 //GENERATED_BODY()展开后 CURRENT_FILE_ID___LINE___GENERATED_BODY //再次替换后 Reflect_Source_Reflect_Public_MyActor_h_12_GENERATED_BODY 2.2、将Reflect_Source_Reflect_Public_MyActor_h_12_GENERATED_BODY宏再次展开 public: Reflect_Source_Reflect_Public_MyActor_h_12_PRIVATE_PROPERTY_OFFSET //空 Reflect_Source_Reflect_Public_MyActor_h_12_RPC_WRAPPERS_NO_PURE_DECLS //空 Reflect_Source_Reflect_Public_MyActor_h_12_INCLASS_NO_PURE_DECLS //2.1 Reflect_Source_Reflect_Public_MyActor_h_12_ENHANCED_CONSTRUCTORS //2.2 三、依次展开以上四个宏 3.1 将Reflect_Source_Reflect_Public_MyActor_h_12_INCLASS_NO_PURE_DECLS宏替换

第一部分private功能:

注册C++原生函数
构建对应UClass的辅助结构体

第二部分public功能:

提供基础特征(类似Traits):ThisClass、Super、ClassFlag、CastFlag、OwnerPacket,new()(仅供编辑器内部使用)
重载 << 实现类的代理序列化

private: //注册C++原生函数以暴露给蓝图虚拟机使用? static void StaticRegisterNativesAMyActor(); //为了构建对应的UClass,是一个辅助结构体 friend struct Z_Construct_UClass_AMyActor_Statics; public: DECLARE_CLASS(AMyActor, AActor, COMPILED_IN_FLAGS(0), CASTCLASS_None, TEXT("/Script/Reflect"), NO_API) DECLARE_SERIALIZER(AMyActor) 3.1.1 展开 DECLARE_CLASS(AMyActor, AActor, COMPILED_IN_FLAGS(0), CASTCLASS_None, TEXT("/Script/Reflect"), NO_API) //#define DECLARE_CLASS( TClass, TSuperClass, TStaticFlags, TStaticCastFlags, TPackage, TRequiredAPI ) //TPackage:包所在路径 //TStaticFlags:类属性标记 EClassFlags(0: 默认,不带任何其他属性) //TStaticCastFlags:类的Cast规则(CASTCLASS_None: 不能转换为默认类型) //TRequiredAPI:Dll导出宏(NO_API: 导出时直接为exe运行,而不用链接API) //3.1:赋值 private: //禁止外界使用 '=' AMyActor& operator=(AMyActor&&); AMyActor& operator=(const AMyActor&); //生成一个自己的UClass NO_API static UClass* GetPrivateStaticClass(); public: /** Bitwise union of #EClassFlags pertaining to this class.*/ //与该类有关的#EClassFlags的按位并集? enum { StaticClassFlags = 0 }; /** Typedef for the base class ({{ typedef-type }}) */ typedef AActor Super; /** Typedef for {{ typedef-type }}. */ typedef AMyActor ThisClass; /** Returns a UClass object representing this class at runtime */ //返回所属的类 inline static UClass* StaticClass() { return GetPrivateStaticClass(); } /** Returns the package this class belongs in */ //返回所属的包 inline static const TCHAR* StaticPackage() { return TEXT("/Script/Reflect"); } /** Returns the static cast flags for this class */ //返回类Cast规则的标记 inline static EClassCastFlags StaticClassCastFlags() { return CASTCLASS_None; } //重载了new 类似NewObject,但仅供引擎使用 /** For internal use only; use StaticConstructObject() to create new objects. */ inline void* operator new(const size_t InSize, EInternal InInternalOnly, UObject * InOuter = (UObject*)GetTransienTEXT("/Script/Reflect")(), FName InName = NAME_None, EObjectFlags InSetFlags = RF_NoFlags) { return StaticAllocateObject(StaticClass(), InOuter, InName, InSetFlags); } /** For internal use only; use StaticConstructObject() to create new objects. */ inline void* operator new(const size_t InSize, EInternal * InMem) { return (void*)InMem; } 3.1.2 展开 DECLARE_SERIALIZER(AMyActor) //重载<<,序列化自己 friend FArchive& operator<<(FArchive & Ar, AMyActor * &Res) { return Ar << (UObject*&)Res; } friend void operator<<(FStructuredArchive::FSlot InSlot, AMyActor * &Res) { InSlot << (UObject*&)Res; } 3.2 将Reflect_Source_Reflect_Public_MyActor_h_12_ENHANCED_CONSTRUCTORS宏展开

主要功能:

private: 关闭移动、拷贝构造功能
public: 提供热更新支持

//四 private: /** Private move- and copy-constructors, should never be used */ //防止移动、拷贝构造 NO_API AMyActor(AMyActor&&); NO_API AMyActor(const AMyActor&); public: //热更新,自行展开 DECLARE_VTABLE_PTR_HELPER_CTOR(NO_API, AMyActor); DEFINE_VTABLE_PTR_HELPER_CTOR_CALLER(AMyActor); DEFINE_DEFAULT_CONSTRUCTOR_CALL(AMyActor); private: 四.总结空AActor中的GENERATED_BODY()功能

private:

注册C++原生函数给蓝图虚拟机 提供构建UClass对应的结构体 关闭移动、拷贝构造函数

public:

提供Actor基础标识:ThisClass、Super、Flags,OwnerPacket,重载类的new() 重载<<实现序列化 提供热重载功能 五、打开自动生成的MyActor.gen.cpp类

在这里插入图片描述

// Fill out your copyright notice in the Description page of Project Settings. #include "test1.h" #include "UObject/GeneratedCppIncludes.h" #include "Reflect/Public/MyActor.h" #ifdef _MSC_VER #pragma warning (push) #pragma warning (disable : 4883) #endif #if NoneAll /** * 一:外部模块执行Z_Construct_UClass_AMyActor构造类 */ //生成的MyActor代码的空链接函数? void EmptyLinkFunctionForGeneratedCodeMyActor() { } // Cross Module References //构造AMyActor对应的UClass的UClass对象,无注册 REFLECT_API UClass* Z_Construct_UClass_AMyActor_NoRegister(); UClass* Z_Construct_UClass_AMyActor_NoRegister() { return AMyActor::StaticClass(); } //构造AMyActor对应的UClass的UClass对象,有注册 REFLECT_API UClass* Z_Construct_UClass_AMyActor(); UClass* Z_Construct_UClass_AMyActor() { //使用ConstructUClass构造UClass static UClass* OuterClass = nullptr; if (!OuterClass) { UE4CodeGen_Private::ConstructUClass(OuterClass, Z_Construct_UClass_AMyActor_Statics::ClassParams); } return OuterClass; } //5.1 构造所在包的UPackage对象 UPackage* Z_Construct_UPackage__Script_Reflect(); /******** 核心:构造UClass ************start**********/ #if 1 ENGINE_API UClass* Z_Construct_UClass_AActor(); //定义辅助构造UClass的结构体 struct Z_Construct_UClass_AMyActor_Statics { //负责构建UClass和UPackage static UObject* (* const DependentSingletons[])(); //元数据参数 #if WITH_METADATA //包含模组相对路径、包含路径 static const UE4CodeGen_Private::FMetaDataPairParam Class_MetaDataParams[]; #endif //类的特性:抽象 (TCppClassTypeTraits::IsAbstract) static const FCppClassTypeInfoStatic StaticCppClassTypeInfo; //Z_Construct_UClass_AMyActor_Statics的核心、存放类的各项参数 //上面的所有参数都会赋值到ClassParams中(DependentSingletons、Class_MetaDataParams、StaticCppClassTypeInfo static const UE4CodeGen_Private::FClassParams ClassParams; }; //初始化DependentSingletons 构造父类的UClass和Package UObject* (* const Z_Construct_UClass_AMyActor_Statics::DependentSingletons[])() = { (UObject * (*)())Z_Construct_UClass_AActor, (UObject * (*)())Z_Construct_UPackage__Script_Reflect, }; //初始化Class_MetaDataParams[] 元数据构造数组,提供包含路径和模组的相对路径 #if WITH_METADATA const UE4CodeGen_Private::FMetaDataPairParam Z_Construct_UClass_AMyActor_Statics::Class_MetaDataParams[] = { { "IncludePath", "MyActor.h" }, { "ModuleRelativePath", "Public/MyActor.h" }, }; #endif //定义c++类的特性,这里定义为抽象 const FCppClassTypeInfoStatic Z_Construct_UClass_AMyActor_Statics::StaticCppClassTypeInfo = { TCppClassTypeTraits::IsAbstract, }; //初始化ClassParams const UE4CodeGen_Private::FClassParams Z_Construct_UClass_AMyActor_Statics::ClassParams = { //ARRAY_COUNT:获取数组数量 &AMyActor::StaticClass, //=ClassNoRegisterFunc nullptr, //UTF8格式的配置名字? &StaticCppClassTypeInfo, //c++特定类型的特性,在.h中定义为IsAbstrct DependentSingletons, //绑定函数指针:DependencySingletonFuncArray nullptr, //函数数组(UFUNCTION) nullptr, //成员变量数组(UPROPERTY) nullptr, //Implement实现接口数组 ARRAY_COUNT(DependentSingletons), //NumDependencySingletons 0, //数组数量 0, //成员变量数量 0, //Implement实现接口数量 0x009000A0u, //类标记 //元数据数组和其数量,服务于编辑器 METADATA_PARAMS(Z_Construct_UClass_AMyActor_Statics::Class_MetaDataParams, ARRAY_COUNT(Z_Construct_UClass_AMyActor_Statics::Class_MetaDataParams)) }; #endif /************* 核心:构造UClass ***********end***********/ // End Cross Module References //静态注册——下文中GetPrivateStaticClass最终调用的注册函数 void AMyActor::StaticRegisterNativesAMyActor() { } IMPLEMENT_CLASS(AMyActor, 1586330386); { //一 展开IMPLEMENT_CLASS(AMyActor, 1586330386) //#define IMPLEMENT_CLASS(TClass, TClassCrc) //延迟注册 static TClassCompiledInDefer AutoInitializeAMyActor(TEXT("AMyActor"), sizeof(AMyActor), AMyActorCrc); //获取到类对应的UClass UClass* AMyActor::GetPrivateStaticClass() { static UClass* PrivateStaticClass = NULL; if (!PrivateStaticClass) { /* this could be handled with templates, but we want it external to avoid code bloat */ GetPrivateStaticClassBody( StaticPackage(), (TCHAR*)TEXT("AMyActor") + 1 + ((StaticClassFlags & CLASS_Deprecated) ? 11 : 0), PrivateStaticClass, StaticRegisterNatives##AMyActor, sizeof(AMyActor), alignof(AMyActor), (EClassFlags)AMyActor::StaticClassFlags, AMyActor::StaticClassCastFlags(), AMyActor::StaticConfigName(), (UClass::ClassConstructorType)InternalConstructor, (UClass::ClassVTableHelperCtorCallerType)InternalVTableHelperCtorCaller, &AMyActor::AddReferencedObjects, &AMyActor::Super::StaticClass, &AMyActor::WithinClass::StaticClass ); } return PrivateStaticClass; } } template REFLECT_API UClass* StaticClass() { return AMyActor::StaticClass(); } //编辑器运行时调用的构造(Z_Construct_UClass_AMyActor)并注册(StaticClass)UClass函数 static FCompiledInDefer Z_CompiledInDefer_UClass_AMyActor(Z_Construct_UClass_AMyActor, &AMyActor::StaticClass, TEXT("/Script/Reflect"), TEXT("AMyActor"), false, nullptr, nullptr, nullptr); DEFINE_VTABLE_PTR_HELPER_CTOR(AMyActor); { //一 //热更新函数实现 AMyActor::AMyActor(FVTableHelper& Helper) : Super(Helper) {}; } 5.1 Z_Construct_UPackage__Script_Reflect()的实现

封装所在包的信息(FPackageParams )后返回对应UPackage

UPackage* Z_Construct_UPackage__Script_Reflect() { static UPackage* ReturnPackage = nullptr; if (!ReturnPackage) { static const UE4CodeGen_Private::FPackageParams PackageParams = { "/Script/Reflect", //NameUTF8 nullptr, //UObject* (* const* SingletonFuncArray)(); 0, //NumSingletons PKG_CompiledIn | 0x00000000, //PackageFlags 0x12C9A2B2, //BodyCRC 0x638DBBFE, //DeclarationsCRC METADATA_PARAMS(nullptr, 0) //元数据数组以及其数量:MetaDataArray,NumMetaData }; //通过上述参数构造UPackage UE4CodeGen_Private::ConstructUPackage(ReturnPackage, PackageParams); } return ReturnPackage; } 六、代码总结: 6.1 GENERATED_BODY()宏

展开后共:

Reflect_Source_Reflect_Public_MyActor_h_11_PRIVATE_PROPERTY_OFFSET
Reflect_Source_Reflect_Public_MyActor_h_11_RPC_WRAPPERS_NO_PURE_DECLS
Reflect_Source_Reflect_Public_MyActor_h_11_INCLASS_NO_PURE_DECLS
Reflect_Source_Reflect_Public_MyActor_h_11_ENHANCED_CONSTRUCTORS

四种宏,展开后第一和第二个宏暂时为空

6.1.1 Reflect_Source_Reflect_Public_MyActor_h_11_INCLASS_NO_PURE_DECLS 主要功能

1、声明部分cpp函数、结构体
2、提供基本Traits (禁用 = ,GetPrivateStaticClass,StaticClassFlags,Super,ThisClass,StaticClass,StaticPackage,StaticClassCastFlags,operator new() )
3、代理序列化 operator<<

6.1.2 Reflect_Source_Reflect_Public_MyActor_h_12_ENHANCED_CONSTRUCTORS主要功能

1、禁止外界使用移动、拷贝构造函数
2、热更新支持
3、提供构造函数包装器

6.2 MyActor.gen.cpp

自动生成的gen.cpp内代码主要用于

构造并注册UClass

注册C++原生函数以暴露给蓝图虚拟机
构建类对应UClass的辅助结构体
GetPrivateStaticClass()
Z_CompiledInDefer_UClass_AMyActor();

部分GENERATED_BODY中声明函数的实现。

七、XMind逻辑分析

空AActor反射生成代码分析 XMind


作者:卅秋



反射 ue4 ue

需要 登录 后方可回复, 如果你还没有账号请 注册新账号