Calling ProcessEvent with PassByRef parameters does nothing

Hello everyone,
I’m trying to call a CustomEvent created on my blueprints, which has a “PassByReference” parameter.

The code i’m using right now is

UFunction *Function = FindFunction(FName(TEXT("TESTING2")));

if(Function)
{
    //This is obviously wrong, i have tried multiple ways
    bool *pb = &MyPassByReferenceBool;
    uint8* Buffer = (uint8*)FMemory_Alloca(Function->ParmsSize);
    FMemory::Memcpy(Buffer, pb, sizeof(bool));
    ProcessEvent(Function, Buffer);
}

I have read that, apparently you cannot use arguments passed by reference on an event… it has to be a function… is this the case?

The problem is that i was creating an EVENT, those by definition cannot return anything, even PassByRef values, this is because on blueprints, there are no return values, but only Out Parameters.

If anone else is trying to manually create a Event with pass by ref value, change it to a function call (creating a graph, and then adding a UK2Node_FunctionEntry), also don’t forget to add pins to this function using:

const UEdGraphSchema_K2 *K2Schema = Cast<const UEdGraphSchema_K2>(Graph->GetSchema()); //Schema will  translate the properties to pin types
		for (TFieldIterator<UProperty> PropIt(SignatureFunction, EFieldIteratorFlags::ExcludeSuper); PropIt; ++PropIt)
		{
			//Properties *PropIt;
			UProperty *Property = *PropIt;
			FEdGraphPinType Type;
			K2Schema->ConvertPropertyToPinType(Property, Type);

			//Create the pin
			FunctionEntry->CreatePin(EGPD_Output, Type, Property->GetNameCPP());
		}

On here, SignatureFunction, is just a simple UFunction that has the signature of the function i’m trying to manually create, it can be done without this, defining the pins manually, but i did this so if the signature changes, i don’t have to worry about re writing much code.

After this just call the function using ProcessEvent on the object that should have the UFunction, and use the same code above to get the outparams.

//Create Buffer and call function
		uint8 *Buffer = (uint8*)FMemory_Alloca(BoundFunction->ParmsSize);
		FMemory::Memzero(Buffer, BoundFunction->ParmsSize);
		OwningInstance->ProcessEvent(BoundFunction, Buffer);
//Obtain the return value (Out Parameters)
		for (TFieldIterator<UProperty> PropIt(BoundFunction, EFieldIteratorFlags::ExcludeSuper); PropIt; ++PropIt)
		{
			UProperty* Property = *PropIt;
			if (Property->HasAnyPropertyFlags(CPF_OutParm)) {
				uint8* outValueAddr = Property->ContainerPtrToValuePtr<uint8>(Buffer);
				bool* pReturn = (bool*)outValueAddr;
				bCanEnterTransmision = *pReturn;
				break;
			}
		}

Hi! Where does memory of Buffer goes free? Is it not necessary?

you know… i’m not entirely sure… on all the examples on epic code… i have not seen a Dealloc being called… so i assume that FMemory_Alloca will get garbage collected after the scope dies

thanks! yes, I also have assumed this but can’t find any confirmation. There is no smart pointer or property, just a raw pointer. It confuses. I can’t realize how it works…