UFunction->Invoke

Hi,

Has anyone ever used the invoke function from a UFunction object ?
I have this:

Actor->ProcessEvent(theFunction, Buffer);

and it works great, but I want to use this:

FFrame frame = FFrame(Actor, theFunction, Buffer, NULL, theFunction->Children);
uint8* ReturnValueAdress = (Buffer + theFunction->ReturnValueOffset);
theFunction->Invoke(Actor, frame, ReturnValueAdress);

because I need the return value. Calling invoke like this crashes the game. Anyone knows what I’m doing wrong or a way to get the returned value from a UFunction ?

I managed to make it work like this:

Actor->ProcessEvent(theFunction, Buffer);

uint8* ReturnValueAdress = Buffer + theFunction->ReturnValueOffset;
int* intp = (int*)ReturnValueAdress; //hardcoded exemple for a int return

The problem I have now is the fact that this only works if the function you process is C++ and has a return value, but blueprint functions don’t have that, they only have out parameters.

Now how do I get those ? :smiley:

Got it.

This is how i got the values from the out parameters after calling ProcessEvent:

for (TFieldIterator<UProperty> PropIt(theFunction, EFieldIteratorFlags::ExcludeSuper); PropIt; ++PropIt)
		{
			UProperty* Property = *PropIt;

			bool isOut = Property->HasAnyPropertyFlags(CPF_OutParm);
			if (!isOut)
				continue;

			uint8* outValueAddr = Property->ContainerPtrToValuePtr<uint8>(Buffer);
			float* floatp = (float*)outValueAddr;//hardcoded example for float
		}

By the way, this is how the buffer was created:

uint8* Buffer = (uint8*)FMemory_Alloca(theFunction->ParmsSize);

And then i fill it with the parameters.

Out of curiosity, as I’m not so familiar with the low level memory management side of things, if I were to find the function to call once at the beginning of the class. Would I be able to define buffer then and simply re-use the value? Or would it need re-definition every call? I don’t know if the memory locations move around. The same question applies to this out parameter gathering, could that be done once on finding the function? Or would it need to be done every time it’s called?

I’m also a little confused by what you mean by “fill it with the parameters” would you be willing to elaborate?

  1. “Would I be able to define buffer then and simply re-use the value?”
    Yes, you can define and assign a value to it once and then reuse it.

  2. “The same question applies to this out parameter gathering, could that be done once on finding the function? Or would it need to be done every time it’s called?”
    You need to do that every time for the out params.

  3. " would you be willing to elaborate?"
    I’m sure you know how a function is usually called (for example):

bool wasAbleToDoIt = someActor->JustDoIt(UsingTheseParams);

We use this method when we know the name of the function, the number of parameters and their types and the return type. So almost always.

But sometimes we don’t know any of those things. That’s where buffers help us.
Think of a buffer as an array of variables/values of different/same type.

That’s why the answer to your first question is yes. It’s the same way you can store a variable and then reuse it.

That’s why the answer to your second question is no. It makes no sens to store the pointer to the return value of a function, then call it again later and expect the return value to be at the same pointer… unless the function returns an actual pointer. I’m not sure I completely understand this question.

What I mean by filling it with parameters is similar to filling an array with values.

uint8* Buffer = (uint8*)FMemory_Alloca(theFunction->ParmsSize); //this is how you create a buffer with the correct size.
float MyShinyNewFloat = 10.0f;
FMemory::Memcpy(Buffer, &MyShinyNewFloat, sizeof(float));//this is how you put the values of the float inside the buffer.