参考虚幻引擎UObjectBase类源代码定义出 UObject对象成员的偏移量
【代码】虚幻引擎UObjectBase类源代码。
·
参考虚幻引擎UObjectBase类源代码定义出自己的 UObject对象成员函数偏移量
源代码路径:
Engine\Source\Runtime\CoreUObject\Public\UObject\UObjectBase.h
// 0 ++ VTable 0x0 + 0x8
/** Flags used to track and report various object states. This needs to be 8 byte aligned on 32-bit
platforms to reduce memory waste */
EObjectFlags ObjectFlags; // 0x8 + 0x4 =0xC
/** Index into GObjectArray...very private. */
int32 InternalIndex; // 0xC +4 = 0x10
/** Class the object belongs to. */
UClass* ClassPrivate; // 0x10 +8 = 0x18
/** Name of this object */
FName NamePrivate; // 0x18 + 4 = 0x1C
/** Object this object resides in. */
UObject* OuterPrivate; //0x1C + 8
定义UObject偏移量为:
struct {
int VTablePtr64 = 0x0;
int ObjectFlags = 0x8;
int Index = 0xC; // 前面有虚表指针和ObjectFlags
int Class = 0x10;
int FName = 0x18;
int Outer = 0x20;
} UObject;
完整UObjectBase源代码:
class COREUOBJECT_API UObjectBase
{
friend class UObjectBaseUtility;
friend COREUOBJECT_API class UClass* Z_Construct_UClass_UObject();
friend class FUObjectArray; // for access to InternalIndex without revealing it to anyone else
friend class FUObjectAllocator; // for access to destructor without revealing it to anyone else
friend COREUOBJECT_API void UObjectForceRegistration(UObjectBase* Object);
friend COREUOBJECT_API void InitializePrivateStaticClass(
class UClass* TClass_Super_StaticClass,
class UClass* TClass_PrivateStaticClass,
class UClass* TClass_WithinClass_StaticClass,
const TCHAR* PackageName,
const TCHAR* Name
);
protected:
UObjectBase() :
NamePrivate(NoInit) // screwy, but the name was already set and we don't want to set it again
{
}
/**
* Constructor used for bootstrapping
* @param InFlags RF_Flags to assign
*/
UObjectBase( EObjectFlags InFlags );
public:
/**
* Constructor used by StaticAllocateObject
* @param InClass non NULL, this gives the class of the new object, if known at this time
* @param InFlags RF_Flags to assign
* @param InInternalFlags EInternalObjectFlags to assign
* @param InOuter outer for this object
* @param InName name of the new object
*/
UObjectBase( UClass* InClass, EObjectFlags InFlags, EInternalObjectFlags InInternalFlags, UObject *InOuter, FName InName );
/**
* Final destructor, removes the object from the object array, and indirectly, from any annotations
**/
virtual ~UObjectBase();
/**
* Emit GC tokens for UObjectBase, this might be UObject::StaticClass or Default__Class
**/
static void EmitBaseReferences(UClass *RootClass);
protected:
/**
* Just change the FName and Outer and rehash into name hash tables. For use by higher level rename functions.
*
* @param NewName new name for this object
* @param NewOuter new outer for this object, if NULL, outer will be unchanged
*/
void LowLevelRename(FName NewName,UObject *NewOuter = NULL);
/** Force any base classes to be registered first */
virtual void RegisterDependencies() {}
/** Enqueue the registration for this object. */
void Register(const TCHAR* PackageName,const TCHAR* Name);
/**
* Convert a boot-strap registered class into a real one, add to uobject array, etc
*
* @param UClassStaticClass Now that it is known, fill in UClass::StaticClass() as the class
*/
virtual void DeferredRegister(UClass *UClassStaticClass,const TCHAR* PackageName,const TCHAR* Name);
private:
/**
* Add a newly created object to the name hash tables and the object array
*
* @param Name name to assign to this uobject
* @param InSetInternalFlags Internal object flags to be set on the object once it's been added to the array
*/
void AddObject(FName Name, EInternalObjectFlags InSetInternalFlags);
public:
/**
* Checks to see if the object appears to be valid
* @return true if this appears to be a valid object
*/
bool IsValidLowLevel() const;
/**
* Faster version of IsValidLowLevel.
* Checks to see if the object appears to be valid by checking pointers and their alignment.
* Name and InternalIndex checks are less accurate than IsValidLowLevel.
* @param bRecursive true if the Class pointer should be checked with IsValidLowLevelFast
* @return true if this appears to be a valid object
*/
bool IsValidLowLevelFast(bool bRecursive = true) const;
/**
* Returns the unique ID of the object...these are reused so it is only unique while the object is alive.
* Useful as a tag.
**/
FORCEINLINE uint32 GetUniqueID() const
{
return (uint32)InternalIndex;
}
FORCEINLINE UClass* GetClass() const
{
return ClassPrivate;
}
FORCEINLINE UObject* GetOuter() const
{
return OuterPrivate;
}
FORCEINLINE FName GetFName() const
{
return NamePrivate;
}
/**
* Returns the stat ID of the object...
**/
FORCEINLINE TStatId GetStatID(bool bForDeferredUse = false) const
{
#if STATS
// this is done to avoid even registering stats for a disabled group (unless we plan on using it later)
if (bForDeferredUse || FThreadStats::IsCollectingData(GET_STATID(STAT_UObjectsStatGroupTester)))
{
if (!StatID.IsValidStat())
{
CreateStatID();
}
return StatID;
}
#endif
return TStatId(); // not doing stats at the moment, or ever
}
private:
/**
* Creates this stat ID for the object...and handle a null this pointer
**/
#if STATS
void CreateStatID() const;
#endif
protected:
/**
* Set the object flags directly
*
**/
FORCEINLINE void SetFlagsTo( EObjectFlags NewFlags )
{
checkfSlow((NewFlags & ~RF_AllFlags) == 0, TEXT("%s flagged as 0x%x but is trying to set flags to RF_AllFlags"), *GetFName().ToString(), (int)ObjectFlags);
ObjectFlags = NewFlags;
}
public:
/**
* Retrieve the object flags directly
*
* @return Flags for this object
**/
FORCEINLINE EObjectFlags GetFlags() const
{
checkfSlow((ObjectFlags & ~RF_AllFlags) == 0, TEXT("%s flagged as RF_AllFlags"), *GetFName().ToString());
return ObjectFlags;
}
/**
* Atomically adds the specified flags.
* Do not use unless you know what you are doing.
* Designed to be used only by parallel GC and UObject loading thread.
*/
FORCENOINLINE void AtomicallySetFlags( EObjectFlags FlagsToAdd )
{
int32 OldFlags = 0;
int32 NewFlags = 0;
do
{
OldFlags = ObjectFlags;
NewFlags = OldFlags | FlagsToAdd;
}
while( FPlatformAtomics::InterlockedCompareExchange( (int32*)&ObjectFlags, NewFlags, OldFlags) != OldFlags );
}
/**
* Atomically clears the specified flags.
* Do not use unless you know what you are doing.
* Designed to be used only by parallel GC and UObject loading thread.
*/
FORCENOINLINE void AtomicallyClearFlags( EObjectFlags FlagsToClear )
{
int32 OldFlags = 0;
int32 NewFlags = 0;
do
{
OldFlags = ObjectFlags;
NewFlags = OldFlags & ~FlagsToClear;
}
while( FPlatformAtomics::InterlockedCompareExchange( (int32*)&ObjectFlags, NewFlags, OldFlags) != OldFlags );
}
private:
// 0 ++++VTable 0x0 + 0x8
/** Flags used to track and report various object states. This needs to be 8 byte aligned on 32-bit
platforms to reduce memory waste */
EObjectFlags ObjectFlags; // 0x8 + 0x4 =0xC
/** Index into GObjectArray...very private. */
int32 InternalIndex; // 0xC +4 = 0x10
/** Class the object belongs to. */
UClass* ClassPrivate; // 0x10 +8 = 0x18
/** Name of this object */
FName NamePrivate; // 0x18 + 4 = 0x1C
/** Object this object resides in. */
UObject* OuterPrivate; //0x1C + 8
/** Stat id of this object, 0 if nobody asked for it yet */
STAT(mutable TStatId StatID;)
// This is used by the reinstancer to re-class and re-archetype the current instances of a class before recompiling
friend class FBlueprintCompileReinstancer;
void SetClass(UClass* NewClass);
#if HACK_HEADER_GENERATOR
// Required by UHT makefiles for internal data serialization.
friend struct FObjectBaseArchiveProxy;
#endif // HACK_HEADER_GENERATOR
};
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
已为社区贡献3条内容
所有评论(0)