From c0a99688f946359e198cc9813f46c15ef5581416 Mon Sep 17 00:00:00 2001 From: Wojtek Figat Date: Mon, 18 Nov 2024 19:00:01 +0100 Subject: [PATCH] Fix passing object reference as out parameter in scripting method invoke --- Source/Engine/Scripting/BinaryModule.cpp | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/Source/Engine/Scripting/BinaryModule.cpp b/Source/Engine/Scripting/BinaryModule.cpp index 3cbce5e26..25abaa335 100644 --- a/Source/Engine/Scripting/BinaryModule.cpp +++ b/Source/Engine/Scripting/BinaryModule.cpp @@ -1264,6 +1264,7 @@ bool ManagedBinaryModule::InvokeMethod(void* method, const Variant& instance, Sp // Marshal parameters void** params = (void**)alloca(parametersCount * sizeof(void*)); + void** outParams = nullptr; bool failed = false; bool hasOutParams = false; for (int32 paramIdx = 0; paramIdx < parametersCount; paramIdx++) @@ -1280,6 +1281,14 @@ bool ManagedBinaryModule::InvokeMethod(void* method, const Variant& instance, Sp LOG(Error, "Failed to marshal parameter {5}:{4} of method '{0}.{1}' (args count: {2}), value type: {6}, value: {3}", String(mMethod->GetParentClass()->GetFullName()), String(mMethod->GetName()), parametersCount, paramValue, MCore::Type::ToString(paramType), paramIdx, paramValue.Type); return true; } + if (isOut && MCore::Type::IsReference(paramType) && MCore::Type::GetType(paramType) == MTypes::Object) + { + // Object passed as out param so pass pointer to the value storage for proper marshalling + if (!outParams) + outParams = (void**)alloca(parametersCount * sizeof(void*)); + outParams[paramIdx] = params[paramIdx]; + params[paramIdx] = &outParams[paramIdx]; + } } // Invoke the method @@ -1344,6 +1353,13 @@ bool ManagedBinaryModule::InvokeMethod(void* method, const Variant& instance, Sp } break; } + default: + { + MType* paramType = mMethod->GetParameterType(paramIdx); + if (MCore::Type::IsReference(paramType) && MCore::Type::GetType(paramType) == MTypes::Object) + paramValue = MUtils::UnboxVariant((MObject*)outParams[paramIdx]); + break; + } } } }