Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

关闭RPC会导致部分函数在非Editor模式下crash #293

Closed
unicodecndddd opened this issue Nov 19, 2021 · 2 comments
Closed

关闭RPC会导致部分函数在非Editor模式下crash #293

unicodecndddd opened this issue Nov 19, 2021 · 2 comments

Comments

@unicodecndddd
Copy link

FunctionDesc.cpp中如下代码

int32 FFunctionDesc::CallUE(lua_State *L, int32 NumParams, void *Userdata)
{

    //
    // call the UFuncton...
//#if !SUPPORTS_RPC_CALL && !WITH_EDITOR
    if (FinalFunction == Function && FinalFunction->HasAnyFunctionFlags(FUNC_Native) && NumCalls == 1)
    {
        //FMemory::Memzero((uint8*)Params + FinalFunction->ParmsSize, FinalFunction->PropertiesSize - FinalFunction->ParmsSize);
        uint8* ReturnValueAddress = FinalFunction->ReturnValueOffset != MAX_uint16 ? (uint8*)Params + FinalFunction->ReturnValueOffset : nullptr;
		FFrame NewStack(Object, FinalFunction, Params, NULL, GetChildProperties(Function));
        NewStack.OutParms = OutParmRec;
        FinalFunction->Invoke(Object, NewStack, ReturnValueAddress);
    }
    else
#endif
    {   
        // Func_NetMuticast both remote and local
        // local automatic checked remote and local,so local first
        if (bLocal)
        {   
            Object->UObject::ProcessEvent(FinalFunction, Params);
        }
        if (bRemote && !bLocal)
        {
            Object->CallRemoteFunction(FinalFunction, Params, nullptr, nullptr);
        }
    }

    int32 NumReturnValues = PostCall(L, NumParams, FirstParamIndex, Params, CleanupFlags);      // push 'out' properties to Lua stack
    return NumReturnValues;
}

如果关闭RPC,会在非Editor模式下走上面的if语句。会触发带out参数的函数的crash。

测试用例如下:

#pragma once

#include "CoreMinimal.h"
#include "Engine/Engine.h"
#include "Kismet/BlueprintFunctionLibrary.h"
#include "TestLibrary.generated.h"

DECLARE_DYNAMIC_DELEGATE_TwoParams(FOnTestEvent, int32, Int, UObject*, Test);

UCLASS()
class GAMEUE_API UTestLibrary : public UBlueprintFunctionLibrary
{
	GENERATED_BODY()
	
	UFUNCTION(BlueprintCallable)
	static int32 Test(const FString& A, int32 B, const FOnTestEvent& Event, const TArray<FSlateColor>& Array);
};

--------------------------------------------------------------------------

#include "TestLibrary.h"

int32 UTestLibrary::Test(const FString& A, int32 B, const FOnTestEvent& Event, const TArray<FSlateColor>& Array)
{
	if (Array.Num() > 0)
	{
		UE_LOG(LogScript, Warning, TEXT("++++++++++++++++++++++++++++++++"));
	}
	return 0;
}

在lua中调用UE4.UTestLibrary.Test(1),会走到if语句中,此时Array已经错误。

@xuyanghuang-tencent
Copy link
Collaborator

xuyanghuang-tencent commented Nov 20, 2021

如果参数是const的话,是无法作为Out参数的,可以在蓝图中添加一个Test调用做对比。如果带const的会出现在节点左侧,不带的才能出现在右侧。

当使用const参数时,蓝图中是必须传入的,否则无法通过编译。而lua中没有对这个做限制,导致不传参数的话就会变成为未初始化的一块内存,这个时候如果在C++侧访问就会出现无法预期的情况,甚至Crash。我看看这能不能做下限制。

xuyanghuang-tencent added a commit that referenced this issue Nov 20, 2021
@xuyanghuang-tencent xuyanghuang-tencent added the pending release This will be released on next version label Nov 20, 2021
@unicodecndddd
Copy link
Author

这里有两个问题。
1.我一开始出错的方法是这样的:

UFUNCTION(BlueprintCallable, meta = (AutoCreateRefTerm = "Event, Array"))
static int32 Test(const FString& A, int32 B, const FOnTestEvent& Event, const TArray<FSlateColor>& Array);

在蓝图下,后两个参数不传也可以通过。现在这个类型检测是认不出来“AutoCreateRefTerm”的。
2.即使我在lua中完整的传递四个参数,如下:

UE4.UTestLibrary.Test("a", 1, {world, function () end}, TArray(UE4.FSlateColor))

array的内存地址依然是错的

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants