Reading Struct Attributes in C++

Hello,

I´m developing a custom Editor Plug-In with custom Slate Fields and etc… and i´m using the UCLASS objects to build all the Field Grids.

Everything is working fine including use the reflection system to parse all the Class Attributes , and i´m having access to all the fields and its values…but…

When i reach a struct attribute all the ContainerPtrToValuePtr and ContainerPtrToValuePtrForDefaults functions fail whith a CoreDump (Memory Fail).

I search all over the web , and i can recurse for all object structure (getting the field names etc…) but when i try extract a value from a struct attribute the system fail.

I spend now more than two weeks trying find out how i can access this values and sadly i not find the solution yet.

Can anyone there help me with it?

This is the code for extract a little FString Value comming from a struct property:

void ZED_DataWidget::ExtractFStringValue(TSharedPtr pAssetField, bool isStrObj)
{
FStrProperty* Property = CastField(pAssetField.Get()->FieldProperty);

if (Property->IsNative())
{
	if (pAssetField.Get()->FieldType == "FString")
	{
		if (Property->IsValidLowLevel())
		{
			if (!isStrObj)
			{
				FString* StrPtr = Property->ContainerPtrToValuePtr<FString>(pAssetField.Get()->FieldOwner);
				if (StrPtr != NULL)
				{
					pAssetField.Get()->FieldStringValue = *StrPtr;
				}
			}
			else
			{
				//pAssetField.Get()->FieldStringValue = "Object Text";
				EPropertyFlags Flags = Property->PropertyFlags;
				FString* StrPtr = Property->ContainerPtrToValuePtrForDefaults<FString>(pAssetField.Get()->FieldStruct,pAssetField.Get()->FieldOwner);
				if (StrPtr != NULL)
				{
					pAssetField.Get()->FieldStringValue = *StrPtr;
				}
			}
		}
		else
		{
			pAssetField.Get()->FieldStringValue = FString("Please! Initialize your " ) + pAssetField.Get()->FieldName + FString(" Attribute!");
		}
	}
}

}
<\code>

Basically on the “If” where the isStrObj is false (Not inside of a struct) the code works like a charm…but in the else(inside of a struct) the code fails.

Any Suggestions or Examples that really work? i try run a lot of examples from the internet , and all of them fails too…

Kind Regards.
Wolff

Hi!

Just to make more easy to answer, i want complement some details:

considering the following code:

FStrProperty* Property = CastField(pAssetField.Get()->FieldProperty);

FString* StrPtr = Property->ContainerPtrToValuePtr(pAssetField.Get()->FieldOwner);

if (StrPtr != NULL)
{
pAssetField.Get()->FieldStringValue = *StrPtr;
}

This code works when the FieldOwner pointer is the address of the Ojbect where the attribute are decleared, but in the case of a struct i must traverse a linked list of properties inside of a UStruct pointer inside of this property.

The question is:

What is the correct pointer to use as FieldOwner?

The Object Itself where the struct are decleared? The Property (FStructProperty) being used to traverse the linked List, the UStruct Pointer being used as a container of the Linked list, or the property itself?

I believe if we find out the correct pointer to use, its possible solve the question.

Please, consider all the pointers as valid pointers, to avoid unecessary waste of time for the person analysing the question.

Kind Regards.
Wolff

The following works for me :

// dummy test struct
FBlueprintCallableFunctionRedirect TestStruct;
TestStruct.ClassName = TEXT("Foobar");

// get the reflected property
FProperty* Prop = TestStruct.StaticStruct()->FindPropertyByName(FName(TEXT("ClassName")));

// Get value
FString Value = *Prop->ContainerPtrToValuePtr<FString>(&TestStruct);
UE_LOG(LogTemp, Warning, TEXT("%s"), *Value);

The pointer you are looking for is the instance of the struct object.

Here is a better example for your case, coming from a struct property in a UCLASS :

// header :
USTRUCT() struct FMyStruct {
    GENERATED_BODY()
    UPROPERTY() FString MyField;
}
UCLASS() class UMyObject : public UObject {
    GENERATED_BODY()
    UPROPERTY() FMyStruct MyStruct;
}

// cpp function :
MyStruct.MyField = TEXT("Foobar");

// get a pointer to the struct instance
FProperty* StructProp = StaticClass()->FindPropertyByName(FName(TEXT("MyStruct")));
void* StructPtr = StructProp->ContainerPtrToValuePtr<void>(this);

// get the reflected property
FProperty* StrProp = ((FMyStruct*)StructPtr)->StaticStruct()->FindPropertyByName(FName(TEXT("MyField")));

// get value in the struct
FString Value = *(StrProp->ContainerPtrToValuePtr<FString>(StructPtr));
UE_LOG(LogTemp, Warning, TEXT("%s"), *Value);
2 Likes

Hi!

Thanks so much!
I will try this and let you know about the progress!

Kind Regards.
Wolff

Thank you, the reflect feature is very useful ! in some script language , it provide "for( propertyName in obj) loop style , the properytName is String , but in UE ,there is similar loop style , it 's very convenient