Aws-sdk-cpp: Need help with lambda function invoke result, get a compile error said: cannot convert 'this' pointer when calling GetPayload method

Created on 24 Aug 2020  路  6Comments  路  Source: aws/aws-sdk-cpp

Platform/OS/Hardware/Device
Using SDK cpp verion on UE4 (4.23)

Describe the question
Hi guys, I need help with getting the lambda function response after invoking it.
I followed InvokeFunction example ( Example Link ) but got a compile error.

Here are the codes:
// In Invoke Function
LambdaClient->InvokeAsync(Request,Handler);

// In Invoke Callback Outcome Function
if (Outcome.IsSuccess())
{
Aws::IOStream& Payload = Outcome.GetResult().GetPayload();
Aws::String FunctionResult;
std::getline(Payload, FunctionResult);
UE_LOG(LogTemp, Verbose, TEXT("%s"), FunctionResult.c_str());
FString FuncResult =FString(FunctionResult.c_str());
}

Additional Question
It's OK to call Outcome.GetResult().GetLogResult(), it would compile successfully.
But when callling Outcome.GetResult().GetPayload(), it would cause this error.

So I tried to use GetLogResult instead of GetPayload, but does anyone know why I got nothing from the LogResult.
I use a lot of console.log in my lambda function script.

Logs/output
Severity Code Description Project File Line Suppression State
Error C2662 'Aws::IOStream &Aws::Lambda::Model::InvokeResult::GetPayload(void)': cannot convert 'this' pointer from 'const R' to 'Aws::Lambda::Model::InvokeResult &'

guidance

Most helpful comment

Wow, you hit the spot!! Thank you @webbnh @KaibaLopez very much. I appreciate your help.

BTW, for the issue that GetLogResult() returns nothing, I found that I thought it is an async function so I set the invocation type to Aws::Lambda::Model::InvocationType::Event, after changing it to Aws::Lambda::Model::InvocationType::RequestResponse it works well.

All 6 comments

Hi @WinterPu ,
I think this is related to unreal engine's logging, not entirely sure yet why it takes Tchar pointers but from looking around I think this would be the best way to get the log:

auto &result = outcome.GetResult();

Aws::IOStream& payload = result.GetPayload();
Aws::String functionResult;
std::getline(payload, functionResult);

FString FuncResult =FString(functionResult.c_str());
UE_LOG(LogTemp, Verbose, TEXT("%s"), *FuncResult);

To know why GetLogResult() doesn't return anything though, I'd have to see how you're decoding it and what your code looks like, for me the sample code works as expected on a simple lambda function.

Hi @KaibaLopez , Thank you for your kind help.
After trying again:

  1. I copied your code, but it still failed to compile, the error code remains the same:
    image
  1. I didn't have any special setting on my lambda function ( I mean I didn't encode my response ). On my client, for the decoding way, I was following this sample code Link
// This part is placed under InvokeAsync return method, the same place as the #1 GetPayload code
            auto & Result = Outcome.GetResult();
        auto ByteLogResult = Aws::Utils::HashingUtils::Base64Decode(Result.GetLogResult());
        Aws::StringStream SSLogResult;
        for (unsigned i = 0; i < ByteLogResult.GetLength(); i++)
            SSLogResult << ByteLogResult.GetItem(i);
        FString LogHeader = FString(SSLogResult.str().c_str());
        UE_LOG(LogTemp, Verbose, TEXT("Log Result Header is: %s"), *LogHeader);

image

I followed InvokeFunction example ( Example Link ) but got a compile error.

You cribbed from the example, changing Invoke() to InvokeAsync()...but hopefully that's not important.

I think the problem is that there are two overloads for GetResult() -- one returns a const R&, and the other returns R&. The reason why you have no problem with GetLogResult() is that it is a const method, and so it doesn't care whether the this pointer (the value returned by GetResult()) is a const or not; however, GetPayload() is _not_ a const method, so it cannot be invoked on a this pointer which is const.

By declaring resultusing auto, I think you're ending up with a const instance and the wrong overload for GetResult().

Try declaring result explicitly as an Aws::Lambda::Model::InvokeResult and see if that works.

Hi @webbnh
Thank you for pointing it out. Because I have created some async functions with almost the same architecture to create game sessions and create player sessions. They work fine, so I don't think that's the problem.

Also, I saw the 2 overloading functions of GetResult(). But after changing the type, it seems it would only take the const one.

// Change from auto to Aws::Lambda::Model::InvokeResult
        Aws::Lambda::Model::InvokeResult & result = Outcome.GetResult();

        Aws::IOStream& payload = result.GetPayload();
        Aws::String functionResult;
        std::getline(payload, functionResult);

        FString FuncResult = FString(functionResult.c_str());
        UE_LOG(LogTemp, Verbose, TEXT("%s"), *FuncResult);

image

Also this is the async callback return function's signature:

void OnLambdaFunctionReturned(const Aws::Lambda::LambdaClient* Client, const Aws::Lambda::Model::InvokeRequest& Request, const Aws::Lambda::Model::InvokeOutcome& Outcome, const std::shared_ptr<const Aws::Client::AsyncCallerContext>& Context)

I thought, maybe it would only use const version of GetResult() because of the const Outcome.
I tried to change Outcome to be the one without const, and it shows:
image

this is the async callback return function's signature:

void OnLambdaFunctionReturned(const Aws::Lambda::LambdaClient* Client, const Aws::Lambda::Model::InvokeRequest& Request, const Aws::Lambda::Model::InvokeOutcome& Outcome, const std::shared_ptr<const Aws::Client::AsyncCallerContext>& Context)

Perhaps that's the issue: according to the docs the Outcome parameter should be a Model::InvokeOutcome, not a const & of one.

Wow, you hit the spot!! Thank you @webbnh @KaibaLopez very much. I appreciate your help.

BTW, for the issue that GetLogResult() returns nothing, I found that I thought it is an async function so I set the invocation type to Aws::Lambda::Model::InvocationType::Event, after changing it to Aws::Lambda::Model::InvocationType::RequestResponse it works well.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

ferrouswheel picture ferrouswheel  路  8Comments

yongchenglv picture yongchenglv  路  5Comments

KeithBlonquist picture KeithBlonquist  路  4Comments

mihaimaruseac picture mihaimaruseac  路  4Comments

nicolasbonnard picture nicolasbonnard  路  4Comments