属性偏移

思考

如果能计算一个属性成员的偏移, 记录该偏移后, 根据指针指向位置, 偏移后可得该属性. 然后可以直接对该属性进行操作.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <iostream>
using namespace std;

#define STRUCT_OFFSET( struc, member ) offsetof(struc, member) // 官方
#define MEMBER_OFFSET( InClass, Member ) ((int)(reinterpret_cast<int>(&(((InClass*)0)->Member))))

class TestClass
{
public:
int x;
int y;
};

int main()
{
TestClass c;
int Offset = MEMBER_OFFSET(TestClass, y);
unsigned char *p = (unsigned char*) & c;
int* p1 = (int*)(p + Offset);
*p1 = 999;
cout << "y:"<<c.y << endl;
return 0;
}

UE方式

UE为什么可以通过指针和FProperty直接定位该属性? 思考上文中的方法, 确实可以.

注册UClass, 调用堆栈:

UHT在*.gen.cpp中生成IMPLEMENT_CLASS

查找IMPLEMENT_CLASS的定义可以看到这里会输入其大小.

最终会设置到UStruct.PropertiesSize上.

AHUD为例:

在生成UClass时候, 会调用Z_Construct_UClass_AHUD

并且根据Params.PropertyArray构建所有FProperty.

即, 在HUD.gen.cpp中查找Z_Construct_UClass_AHUD_Statics::PropPointers的来源.

属性偏移

所以, 在创建FProperty的时候, 就已经知道其偏移位置了.