关于ue c++中的GENERATED_BODY宏的展开
·
创建一个MyClassTest.h文件和MyClassTest.cpp文件:

编译后会生成文件名.generated.h和文件名.gen.cpp文件。
接下来看MyClassTest.h中的GENERATED_BODY():
在ObjectMacros.h文件中对此宏做了一层层定义,
- 可以看出GENERATED_BODY()最终会转换为一个由文件ID(CURRENT_FILE_ID)、行号(LINE)、"GENERATED_BODY"字符组合成的标记。


(可以看出来这个CURRENT_FILE_ID是该.h文件所在项目的路径)
(其中行号是GENERATED_BODY在.h文件中的行号)
综上可得 GENERATED_BODY() 转换为了Survive_Source_MYUEPROJECT_Public_MyClassTest_h_15_GENERATED_BODY
- 而这个结果在.generated.h文件中又继续宏定义了:

- 需要继续一步步展开:

PRAGMA_DISABLE_DEPRECATION_WARNINGS/PRAGMA_ENABLE_DEPRECATION_WARNINGS
(这两个宏是用来开启/关闭禁止编译器过期警告.)
综上最终GENERATED_BODY()展开差不多就变为了:
MyClassTest.gen.cpp文件内容如下:
#include "GeneratedCppIncludes.h"
#include "Public/MyClassTest.h"
#ifdef _MSC_VER
#pragma warning (push)
#pragma warning (disable : 4883)
#endif
PRAGMA_DISABLE_DEPRECATION_WARNINGS
void EmptyLinkFunctionForGeneratedCodeMyClassTest() {}//链接占位符,帮助保证UBT生成的代码在编译后的二进制文件中是可链接的
// Cross Module References
MYUEPROJECT_API UClass* Z_Construct_UClass_UMyClassTest_NoRegister();//返回一个指向 UMyClassTest 类的 UClass 指针,但不进行注册,这样可以访问这个类的特性,但不会将其注册到引擎的内存管理系统中 确保了类的快速查询而不进行实际注册,帮助优化性能和维护引擎的稳定性
MYUEPROJECT_API UClass* Z_Construct_UClass_UMyClassTest();//完整的类构造和注册过程的实现
COREUOBJECT_API UClass* Z_Construct_UClass_UObject();//构造和注册 UObject 类及其属性和方法
UPackage* Z_Construct_UPackage__Script_myueproject();//Win64\UE4Editor\Inc\myueproject下有myueproject.init.gen.cpp文件实现了函数
// End Cross Module References
void UMyClassTest::StaticRegisterNativesUMyClassTest()//将定义的本地方法注册到引擎的反射系统中
{
UClass* Class = UMyClassTest::StaticClass();
static const FNameNativePtrPair Funcs[] = {
{ "MyFunc", (Native)&UMyClassTest::execMyFunc },
};
FNativeFunctionRegistrar::RegisterFunctions(Class, Funcs, ARRAY_COUNT(Funcs));
}
UFunction* Z_Construct_UFunction_UMyClassTest_MyFunc()
{
struct MyClassTest_eventMyFunc_Parms
{
uint32 a;
int32 ReturnValue;
};
static UFunction* ReturnFunction = nullptr;
if (!ReturnFunction)
{
static const UE4CodeGen_Private::FIntPropertyParams NewProp_ReturnValue = { UE4CodeGen_Private::EPropertyClass::Int, "ReturnValue", RF_Public|RF_Transient|RF_MarkAsNative, 0x0010000000000580, 1, nullptr, STRUCT_OFFSET(MyClassTest_eventMyFunc_Parms, ReturnValue), METADATA_PARAMS(nullptr, 0) };
static const UE4CodeGen_Private::FUInt32PropertyParams NewProp_a = { UE4CodeGen_Private::EPropertyClass::UInt32, "a", RF_Public|RF_Transient|RF_MarkAsNative, 0x0010000000000080, 1, nullptr, STRUCT_OFFSET(MyClassTest_eventMyFunc_Parms, a), METADATA_PARAMS(nullptr, 0) };
static const UE4CodeGen_Private::FPropertyParamsBase* const PropPointers[] = {
(const UE4CodeGen_Private::FPropertyParamsBase*)&NewProp_ReturnValue,
(const UE4CodeGen_Private::FPropertyParamsBase*)&NewProp_a,
};
#if WITH_METADATA
static const UE4CodeGen_Private::FMetaDataPairParam Function_MetaDataParams[] = {
{ "ModuleRelativePath", "Public/MyClassTest.h" },
};
#endif
static const UE4CodeGen_Private::FFunctionParams FuncParams = { (UObject*(*)())Z_Construct_UClass_UMyClassTest, "MyFunc", RF_Public|RF_Transient|RF_MarkAsNative, nullptr, (EFunctionFlags)0x04020401, sizeof(MyClassTest_eventMyFunc_Parms), PropPointers, ARRAY_COUNT(PropPointers), /*0, 0,*/ METADATA_PARAMS(Function_MetaDataParams, ARRAY_COUNT(Function_MetaDataParams)) };
UE4CodeGen_Private::ConstructUFunction(ReturnFunction, FuncParams);
}
return ReturnFunction;
}
UClass* Z_Construct_UClass_UMyClassTest_NoRegister()
{
return UMyClassTest::StaticClass();
}
UClass* Z_Construct_UClass_UMyClassTest()
{
static UClass* OuterClass = nullptr;
if (!OuterClass) // 只构造一次UClass
{
static UObject* (*const DependentSingletons[])() = {//列出了UMyClassTest类所依赖的父类和模块
(UObject* (*)())Z_Construct_UClass_UObject,
(UObject* (*)())Z_Construct_UPackage__Script_myueproject,
};
static const FClassFunctionLinkInfo FuncInfo[] = {
{ &Z_Construct_UFunction_UMyClassTest_MyFunc, "MyFunc" }, // 类中的方法的信息
};
#if WITH_METADATA
static const UE4CodeGen_Private::FMetaDataPairParam Class_MetaDataParams[] = {//存储类的元数据,例如类的头文件路径和相对模块路径
{ "IncludePath", "MyClassTest.h" },
{ "ModuleRelativePath", "Public/MyClassTest.h" },
};
#endif
#if WITH_METADATA
static const UE4CodeGen_Private::FMetaDataPairParam NewProp_MyID_MetaData[] = {//变量属性数据
{ "ModuleRelativePath", "Public/MyClassTest.h" },
};
#endif
//NewProp_MyID属性的类型、访问修饰符、元数据等
static const UE4CodeGen_Private::FIntPropertyParams NewProp_MyID = { UE4CodeGen_Private::EPropertyClass::Int, "MyID", RF_Public|RF_Transient|RF_MarkAsNative, 0x0010000000000000, 1, nullptr, STRUCT_OFFSET(UMyClassTest, MyID), METADATA_PARAMS(NewProp_MyID_MetaData, ARRAY_COUNT(NewProp_MyID_MetaData)) };
static const UE4CodeGen_Private::FPropertyParamsBase* const PropPointers[] = {//包含类中所有属性的指针。这些指针用于反射和序列化时的属性访问。
(const UE4CodeGen_Private::FPropertyParamsBase*)&NewProp_MyID,
};
static const FCppClassTypeInfoStatic StaticCppClassTypeInfo = {
TCppClassTypeTraits<UMyClassTest>::IsAbstract,//该类是否是一个抽象类
};
static const UE4CodeGen_Private::FClassParams ClassParams = {//包含了所有与UMyClassTest类有关的参数
&UMyClassTest::StaticClass,
DependentSingletons, ARRAY_COUNT(DependentSingletons),
0x00000080u,
FuncInfo, ARRAY_COUNT(FuncInfo),
PropPointers, ARRAY_COUNT(PropPointers),
nullptr,
&StaticCppClassTypeInfo,
nullptr, 0,
METADATA_PARAMS(Class_MetaDataParams, ARRAY_COUNT(Class_MetaDataParams))
};
UE4CodeGen_Private::ConstructUClass(OuterClass, ClassParams);//调用引擎构造接口来实际构造UClass对象并进行注册
}
return OuterClass;
}
IMPLEMENT_CLASS(UMyClassTest, 10187216);//编译时调用构造函数来注册特定的类,据说会调用Z_Construct_UClass_UMyClassTest构造函数
//<==>IMPLEMENT_CLASS宏展开如下:
//static UMyClassTestCompiledInDefer<UMyClassTest> AutoInitialize##UMyClassTest(TEXT(#UMyClassTest), sizeof(UMyClassTest), 10187216);
//UClass* UMyClassTest::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(#UMyClassTest) + 1 + ((StaticClassFlags & CLASS_Deprecated) ? 11 : 0),
// PrivateStaticClass,
// StaticRegisterNatives##UMyClassTest,
// sizeof(UMyClassTest),
// (EClassFlags)UMyClassTest::StaticClassFlags,
// UMyClassTest::StaticClassCastFlags(),
// UMyClassTest::StaticConfigName(),
// (UClass::ClassConstructorType)InternalConstructor<UMyClassTest>,
// (UClass::ClassVTableHelperCtorCallerType)InternalVTableHelperCtorCaller<UMyClassTest>,
// & UMyClassTest::AddReferencedObjects,
// & UMyClassTest::Super::StaticClass,
// & UMyClassTest::WithinClass::StaticClass
// );
// }
// return PrivateStaticClass;
//}
static FCompiledInDefer Z_CompiledInDefer_UClass_UMyClassTest(Z_Construct_UClass_UMyClassTest, &UMyClassTest::StaticClass, TEXT("/Script/myueproject"), TEXT("UMyClassTest"), false, nullptr, nullptr, nullptr);
DEFINE_VTABLE_PTR_HELPER_CTOR(UMyClassTest);
PRAGMA_ENABLE_DEPRECATION_WARNINGS
#ifdef _MSC_VER
#pragma warning (pop)
#endif
更多推荐


所有评论(0)