CallFunctionByNameWithArguments支持返回值获取

          ue4中C++与l蓝图交互或外部程序基于字符串调用UObject派生类函数时会常用到CallFunctionByNameWithArguments函数,调用时一个比较麻烦的问题时调用完了无法获取返回值,主要原因是该函数在调用ProcessEvent函数时,并没对函数调用返回值进行处理,而是直接忽略掉了,而实际上该函数中完全可以获得函数的返回值。

————————————————

// Call native function or UObject::ProcessInternal.

const bool bHasReturnParam = Function->ReturnValueOffset != MAX_uint16;

uint8* ReturnValueAddress = bHasReturnParam ? ((uint8*)Parms + Function->ReturnValueOffset) : nullptr;

Function->Invoke(this, NewStack, ReturnValueAddress);

————————————————

 

        为了能够对函数返回值进行处理,我们的思路就是重载UObject的ProcessEvent函数,这个函数恰好时要给虚函数。

/** Called by VM to execute a UFunction with a filled in UStruct of parameters */

virtual void ProcessEvent( UFunction* Function, void* Parms );

————————————————

        然后使用UFunction中书参数处理的一些方法,重新解析返回值,并且通过成员变量作临时保存,然后在合适的地方将临时保存的返回值作为调用返回值返回出去,主要实现代码如下:

void ACallFunctionGameModeBase::ProcessEvent(UFunction* Function, void* Parms)

{

Super::ProcessEvent(Function, Parms);

 

FString FuncName;

Function->GetName(FuncName);

if (FuncName.Compare(TEXT("CallMe")) == 0)

{

//处理函数调用返回值

const bool bHasReturnParam = Function->ReturnValueOffset != MAX_uint16;

if (bHasReturnParam)

{

uint8* ReturnValueAddress = ((uint8*)Parms + Function->ReturnValueOffset);

 

// find the last parameter

FProperty* Parameter = nullptr;

for (TFieldIterator ParamIt(Function); ParamIt; ++ParamIt)

{

Parameter = *ParamIt;

// Skip the return value; it never has data on the bytecode stack and was added to the output params chain before this loop

if (Parameter->HasAnyPropertyFlags(CPF_ReturnParm))

{

ReturnStr.Empty();

Parameter->ExportTextItem(ReturnStr, ReturnValueAddress, nullptr, nullptr, PPF_None);

break;

}

}

 

//GEngine->AddOnScreenDebugMessage(0, 5.0f, FColor::Yellow, ReturnStr);

}

}

示范代码下载地址:https://github.com/litar77/CallFunctionByNameReturnValue

————————————————

版权声明:本文为CSDN博主「山中涛大爷」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。

原文链接:https://blog.csdn.net/sandygull/article/details/121070107