4.6 KiB
Raw Blame History

IsAlwaysAccessible

  • 功能描述: 指定UHT在生成文件的时候总是可以访问到改结构的声明否则要在gen.cpp里生成镜像结构定义
  • 元数据类型: bool
  • 引擎模块: UHT
  • 限制类型: 只在NoExportTypes.h供UHT使用
  • 常用程度: 0

指定该结构的声明是否在UHT为NoExportTypes.h生成的gen.cpp里总是可以访问到。

换句话说其实就是是否这些结构在GeneratedCppIncludes.h的声明里可以找到。如果不可以找到那在后面生成Z_Construct_UScriptStruct_FMatrix44d_Statics这种类似的时候就得再自己定义一个镜像结构定义。如果可以找到比如FGuid则就不需要。

因此这只是一个手动的内部标记帮助UHT程序识别哪些结构要再创建镜像结构定义。

在NoExportTypes.h查看各个结构的时候会发现有些结构85/135会标上IsAlwaysAccessible而有些没有。这是因为UHT在为NoExportTypes.h生成gen.cpp的时候

\UnrealEngine\Engine\Source\Runtime\CoreUObject\Public\UObject\GeneratedCppIncludes.h
#include "UObject/Object.h"
#include "UObject/UObjectGlobals.h"
#include "UObject/CoreNative.h"
#include "UObject/Class.h"
#include "UObject/MetaData.h"
#include "UObject/UnrealType.h"
#include "UObject/EnumProperty.h"
#include "UObject/TextProperty.h"
#include "UObject/FieldPathProperty.h"

#if UE_ENABLE_INCLUDE_ORDER_DEPRECATED_IN_5_2
#include "CoreMinimal.h"
#endif

\Hello\Intermediate\Build\Win64\HelloEditor\Inc\CoreUObject\UHT\NoExportTypes.gen.cpp
// Copyright Epic Games, Inc. All Rights Reserved.
/*===========================================================================
	Generated code exported from UnrealHeaderTool.
	DO NOT modify this manually! Edit the corresponding .h files instead!
===========================================================================*/

//以下这两行
#include "UObject/GeneratedCppIncludes.h"//A
#include "UObject/NoExportTypes.h"//B
PRAGMA_DISABLE_DEPRECATION_WARNINGS
void EmptyLinkFunctionForGeneratedCodeNoExportTypes() {}

在最开头的两个include里如果可以直接找到该struct的定义则在gen.cpp中的A和B处需要结构定义的时候就不需要再额外去找定义了。

const UECodeGen_Private::FStructParams Z_Construct_UScriptStruct_FMatrix44f_Statics::ReturnStructParams = {
		(UObject* (*)())Z_Construct_UPackage__Script_CoreUObject,
		nullptr,
		nullptr,
		"Matrix44f",
		Z_Construct_UScriptStruct_FMatrix44f_Statics::PropPointers,
		UE_ARRAY_COUNT(Z_Construct_UScriptStruct_FMatrix44f_Statics::PropPointers),
		sizeof(FMatrix44f),//这个A
		alignof(FMatrix44f),//这个B
		RF_Public|RF_Transient|RF_MarkAsNative,
		EStructFlags(0x00000038),
		METADATA_PARAMS(UE_ARRAY_COUNT(Z_Construct_UScriptStruct_FMatrix44f_Statics::Struct_MetaDataParams), Z_Construct_UScriptStruct_FMatrix44f_Statics::Struct_MetaDataParams)
	};

如果找不到比如FMatrix44f是定义在Engine\Source\Runtime\Core\Public\Math\Matrix.h则必须为它生成一个一模一样的定义不include的作用是加快编译)

struct Z_Construct_UScriptStruct_FMatrix44f_Statics
	{
		struct FMatrix44f //内存布局一致的定义
		{
			FPlane4f XPlane;
			FPlane4f YPlane;
			FPlane4f ZPlane;
			FPlane4f WPlane;
		};

		static_assert(sizeof(FMatrix44f) < MAX_uint16);
		static_assert(alignof(FMatrix44f) < MAX_uint8);

当然如果子字段或者父类也找不到定义则只需要把父定义先写在前面就可以了。因此cs里的FindNoExportStructsRecursive就是为了找到其相关的结构。没有标IsAlwaysAccessible则意味着要生成假的结构定义

private static void FindNoExportStructsRecursive(List<UhtScriptStruct> outScriptStructs, UhtStruct structObj)
		{
			for (UhtStruct? current = structObj; current != null; current = current.SuperStruct)
			{
				// Is isn't true for noexport structs
				if (current is UhtScriptStruct scriptStruct)
				{
					if (scriptStruct.ScriptStructFlags.HasAnyFlags(EStructFlags.Native))
					{
						break;
					}

					// these are a special cases that already exists and if wrong if exported naively
					if (!scriptStruct.IsAlwaysAccessible)
					{
						outScriptStructs.Remove(scriptStruct);
						outScriptStructs.Add(scriptStruct);
					}
				}

				foreach (UhtType type in current.Children)
				{
					if (type is UhtProperty property)
					{
						foreach (UhtType referenceType in property.EnumerateReferencedTypes())
						{
							if (referenceType is UhtScriptStruct propertyScriptStruct)
							{
								FindNoExportStructsRecursive(outScriptStructs, propertyScriptStruct);
							}
						}
					}
				}
			}
		}