Run Blueprint Function and get Return Parameter

Hello,

I am working some code that gets a blueprint function by name, calls it and gets the return value of said blueprint function.

UFunction* func = Object->GetClass()->FindFunctionByName(FName("Testing"));

if (func == nullptr)
{
	GEngine->AddOnScreenDebugMessage(12332, 10.0, FColor::Red, "Could not find Function 'Testing'!");
	return;
}

FStructOnScope FuncParam(func);
FProperty* RetuenProp = nullptr;

FString Value;

for (TFieldIterator<FProperty> It(func); It; ++It)
{
	FProperty* Prop = *It;

	if (Prop->HasAnyPropertyFlags(CPF_ReturnParm))
	{
		RetuenProp = Prop;
		GEngine->AddOnScreenDebugMessage(12332, 10.0, FColor::Red, "Found Return Node for'Testing'!");
	}
	else
	{
	}
}

Object->ProcessEvent(func, FuncParam.GetStructMemory());

I can successfully find and execute the function. However, I cannot get the return value as the CPF_ReturnParam is never set.

In my testing function, i simply add a return node with a string with text in it. I’ve also tried promoting the blueprint return value to a variable and no luck.

EDIT 1

Sorry, I forgot to mention that I ran a check to see if it was getting any properties, and the return parameter property was showing up, just without the CPF_ReturnParm flag.

I have moved forward a bit, to this:

UFunction* func = Object->GetClass()->FindFunctionByName(FName("Testing"));

if (func == nullptr)
{
	GEngine->AddOnScreenDebugMessage(12332, 10.0, FColor::Red, "Could not find Function 'Testing'!");
	return;
}

FStructOnScope FuncParam(func);

FStrProperty* StrReturnValue = nullptr;

FString Value;

for (TFieldIterator<FProperty> It(func); It; ++It)
{
	FProperty* Prop = *It;

	if (Prop->HasAnyPropertyFlags(CPF_ReturnParm))
	{
		StrReturnValue = CastField<FStrProperty>(Prop);
		GEngine->AddOnScreenDebugMessage(12332, 10.0, FColor::Red, "Found Return Node for'Testing'!");
	}
	else
	{
		FStrProperty* StrProperty = CastFieldChecked<FStrProperty>(Prop);

		if (StrProperty)
		{
			GEngine->AddOnScreenDebugMessage(12332, 10.0, FColor::Red, "Successfully converted FProperty to FStrProperty");

			GEngine->AddOnScreenDebugMessage(12332, 10.0, FColor::Red, StrProperty->GetDisplayNameText().ToString());

			StrReturnValue = StrProperty;
		}
	}
}

Object->ProcessEvent(func, FuncParam.GetStructMemory());

if (StrReturnValue != nullptr)
{
	GEngine->AddOnScreenDebugMessage(12331, 10.0, FColor::Red, "StrReturnValue is valid!", false);

	Value = StrReturnValue->GetPropertyValue_InContainer(func);

	if (Value.IsEmpty())
	{
		GEngine->AddOnScreenDebugMessage(12331, 10.0, FColor::Red, "Value is Empty!", false);
	}
	else
	{
		FString Text = "Lenght of Value is: " + FString::FromInt(Value.Len());
		GEngine->AddOnScreenDebugMessage(12331, 10.0, FColor::Red, Text, false);
		UE_LOG(LogTemp, Warning, TEXT("%s"), *Value);
	}

}

However, Value returns garbage memory. I’m not sure if its because of how I am trying to get the property value. I haven’t needed to use properties since before epic updated their property system.

Note: I had posted this question a couple of days ago, but for some reason when I edited the post, it said waiting for moderator approval. Which never happened.

I feel kind of stupid now.

Value = StrReturnValue->GetPropertyValue_InContainer(FuncParam.GetStructMemory());

So at the end of UObject->ProcessEvent(UFunction, void*), Epic performs an FMemory::Memcpy, and copies all the out param values to the param memory address passed in, which in my case was FuncParam.GetStructMemory();

// Destroy local variables except function parameters.!! see also UObject::CallFunctionByNameWithArguments
// also copy back constructed value parms here so the correct copy is destroyed when the event function returns

This would be the obvious reason for getting the garbage memory from before, as I was pointing to the wrong memory address (func), when in fact, I was supposed to pass in the memory address of the container that actually contained the value (After ProcessEvent took place).

I’m still pretty raw on memory.

Thanks for your help.