Skip to content

Commit 0027500

Browse files
committed
update
1 parent fa30ccf commit 0027500

File tree

1 file changed

+18
-4
lines changed

1 file changed

+18
-4
lines changed

_posts/UE/Engine Basic/2025-06-17 UObject Initialization in Unreal.md

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,18 @@
1+
### Flow
2+
* 加载 CoreUObject 模块时,触发 uobject 类的 uclass 构造,以及静态数据的注册
3+
* 随后 `FCoreUObjectModule::StartupModule` 中调用 `UClassRegisterAllCompiledInClasses`,创建出各个类的 uclass,并把这些 uclass 注册到 `FPendingRegistrant` 单链表中
4+
* 后续回调函数 `InitUObject``FEngineLoop::AppInit`(它是在 `PreInitPreStartupScreen` 阶段)中被调用
5+
* 初始化 `GUObjectAllocator`(它负责分配 UObject 占用的内存),`GUObjectArray`(它负责分配 `FUObjectItem` 占用的内存),这之后就可以使用 `NewObject` API 了
6+
* 调用 `UObjectProcessRegistrants` 使用 `FPendingRegistrant` 构成的单链表(注意,SuperStruct 指针在一开始创建 uclass 的时候就设置好了。因为子类的 uclass 创建依赖于父类的 uclass 创建)
7+
* 将 uclass 注册到全局的 object array 中(这下有了 `NamePrivate`,`InternalIndex`)
8+
* 创建 uclass 的 package(`OuterPrivate` 指向该 package)
9+
* 将 `ClassPrivate` 指向 uclass 类的 uclass(因此 uclass 类的 uclass 的 `ClassPrivate` 指向自己)
10+
* 创建 global transient package
11+
*`FEngineLoop::PreInitPostStartupScreen` 中会调用 `ProcessNewlyLoadedUObjects`,这个函数就是一个全家桶,它除了调用 `UClassRegisterAllCompiledInClasses``UObjectProcessRegistrants` 来创建和注册各个类的 uclass 之外,会最终将所有 uproperty 和 ufunction 的信息写入到 uclass 中,并创建 CDO
12+
*`FEngineLoop::PreInitPostStartupScreen` 中会调用 `FUObjectArray::CloseDisregardForGC`,这个函数中也会调用一次 `ProcessNewlyLoadedUObjects`
13+
### Note 1
114
gen.cpp 中的 `IMPLEMENT_CLASS` 宏定义了 static 的 uclass 指针,这是我们能通过 `Class::StaticClass` 接口拿到 uclass 指针的原因
215

3-
416
整个 CoreUObject 模块的生成信息是特化的,源代码中没有出现 `include xxx.generated.h` 等,查看 Intermediate 目录中 CoreUObject 的生成信息包括
517
```
618
CoreNetTypes.gen.cpp CoreOnline.gen.cpp CoreUObject.init.gen.cpp NoExportTypes.generated.h
@@ -12,9 +24,7 @@ CoreNetTypes.generated.h CoreOnline.generated.h NoExportTypes.gen.cpp
1224
```c++
1325
static TArray<FFieldCompiledInInfo*> DeferredClassRegistration;
1426
```
15-
16-
**TODO:但是 `IMPLEMENT_CORE_INTRINSIC_CLASS``IMPLEMENT_INTRINSIC_CLASS` 还会额外定义一个静态对象 `FCompiledInDefer`**
17-
27+
另外一个全局信息是 `FCompiledInDefer`(这俩在 UE5 里变为了 Inner Register 和 Outer Register,不过充当的角色都是一样的)
1828

1929
`DeferredClassRegistration``UClassRegisterAllCompiledInClasses` 函数中使用,该函数调用 `Class::StaticClass` 接口,将这些类的 uclass 都创建出来
2030

@@ -28,7 +38,11 @@ static TArray<FFieldCompiledInInfo*> DeferredClassRegistration;
2838
* `UObjectBaseInit`
2939
* `ProcessNewlyLoadedUObjects`
3040

41+
uobject 的 uclass 也是一个 uobject,因此这个 uclass 也有 `ClassPrivate` 指针,它指向的是 uclass 的 uclass,但 uclass 又是 uobject 的子类。因此这里会存在一个循环依赖的问题。UE 里是先构建 uobject 的 uclass,此时这个 uclass 的 `ClassPrivate` 指针为空
42+
43+
3144

45+
TODO:解释 UE::GC::DeclareIntrinsicMembers
3246

3347
参考
3448
* [UObject(五)类型系统信息收集](https://zhuanlan.zhihu.com/p/26019216)

0 commit comments

Comments
 (0)