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