diff --git a/src/coreclr/vm/methodtable.cpp b/src/coreclr/vm/methodtable.cpp index 5bce8f14b60bc..c36de5719ba57 100644 --- a/src/coreclr/vm/methodtable.cpp +++ b/src/coreclr/vm/methodtable.cpp @@ -481,6 +481,22 @@ PTR_MethodTable InterfaceInfo_t::GetApproxMethodTable(Module * pContainingModule MethodTable *pServerMT = (*pServer)->GetMethodTable(); PREFIX_ASSUME(pServerMT != NULL); +#ifdef FEATURE_COMINTEROP + if (pServerMT->IsComObjectType() && !pItfMD->HasMethodInstantiation()) + { + // interop needs an exact MethodDesc + pItfMD = MethodDesc::FindOrCreateAssociatedMethodDesc( + pItfMD, + ownerType.GetMethodTable(), + FALSE, // forceBoxedEntryPoint + Instantiation(), // methodInst + FALSE, // allowInstParam + TRUE); // forceRemotableMethod + + RETURN(pServerMT->GetMethodDescForComInterfaceMethod(pItfMD, false)); + } +#endif // !FEATURE_COMINTEROP + // For IDynamicInterfaceCastable, instead of trying to find method implementation in the real object type // we call GetInterfaceImplementation on the object and call GetMethodDescForInterfaceMethod // with whatever type it returns. @@ -501,22 +517,6 @@ PTR_MethodTable InterfaceInfo_t::GetApproxMethodTable(Module * pContainingModule RETURN(implTypeHandle.GetMethodTable()->GetMethodDescForInterfaceMethod(ownerType, pItfMD, TRUE /* throwOnConflict */)); } -#ifdef FEATURE_COMINTEROP - if (pServerMT->IsComObjectType() && !pItfMD->HasMethodInstantiation()) - { - // interop needs an exact MethodDesc - pItfMD = MethodDesc::FindOrCreateAssociatedMethodDesc( - pItfMD, - ownerType.GetMethodTable(), - FALSE, // forceBoxedEntryPoint - Instantiation(), // methodInst - FALSE, // allowInstParam - TRUE); // forceRemotableMethod - - RETURN(pServerMT->GetMethodDescForComInterfaceMethod(pItfMD, false)); - } -#endif // !FEATURE_COMINTEROP - // Handle pure COM+ types. RETURN (pServerMT->GetMethodDescForInterfaceMethod(ownerType, pItfMD, TRUE /* throwOnConflict */)); } diff --git a/src/tests/Interop/COM/NETClients/Primitives/CallViaReflectionTests.cs b/src/tests/Interop/COM/NETClients/Primitives/CallViaReflectionTests.cs new file mode 100644 index 0000000000000..561f6c685abb8 --- /dev/null +++ b/src/tests/Interop/COM/NETClients/Primitives/CallViaReflectionTests.cs @@ -0,0 +1,33 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +namespace NetClient +{ + using System; + using System.Reflection; + using Xunit; + + class CallViaReflectionTests + { + private readonly Server.Contract.Servers.NumericTesting server; + + public CallViaReflectionTests() + { + this.server = (Server.Contract.Servers.NumericTesting)new Server.Contract.Servers.NumericTestingClass(); + } + + public void Run() + { + Console.WriteLine(nameof(CallViaReflectionTests)); + this.InvokeInstanceMethod(); + } + + private void InvokeInstanceMethod() + { + MethodInfo minfo = typeof(Server.Contract.INumericTesting).GetMethod("Add_Int")!; + object[] parameters = new object[2] { 10, 20 }; + int sum = (int)minfo.Invoke(this.server, parameters); + Assert.Equal(30, sum); + } + } +} \ No newline at end of file diff --git a/src/tests/Interop/COM/NETClients/Primitives/NETClientPrimitives.csproj b/src/tests/Interop/COM/NETClients/Primitives/NETClientPrimitives.csproj index a9726c2a592ef..2a47fa1ae8a39 100644 --- a/src/tests/Interop/COM/NETClients/Primitives/NETClientPrimitives.csproj +++ b/src/tests/Interop/COM/NETClients/Primitives/NETClientPrimitives.csproj @@ -7,6 +7,7 @@ + diff --git a/src/tests/Interop/COM/NETClients/Primitives/Program.cs b/src/tests/Interop/COM/NETClients/Primitives/Program.cs index b45595fe67f60..e487e15d08de9 100644 --- a/src/tests/Interop/COM/NETClients/Primitives/Program.cs +++ b/src/tests/Interop/COM/NETClients/Primitives/Program.cs @@ -40,6 +40,7 @@ private static void RunTests() new StringTests().Run(); new ErrorTests().Run(); new ColorTests().Run(); + new CallViaReflectionTests().Run(); } } }