diff --git a/src/coreclr/vm/callconvbuilder.cpp b/src/coreclr/vm/callconvbuilder.cpp index 60d5d5eb0bbe71..a42b3b908a07f7 100644 --- a/src/coreclr/vm/callconvbuilder.cpp +++ b/src/coreclr/vm/callconvbuilder.cpp @@ -550,7 +550,7 @@ bool CallConv::TryGetCallingConventionFromUnmanagedCallersOnly(_In_ MethodDesc* // UnmanagedCallersOnly each // have optional named arguments. - CaNamedArg namedArgs[2]; + CaNamedArg namedArgs[3]; // For the UnmanagedCallersOnly scenario. CaType caCallConvs; @@ -563,6 +563,9 @@ bool CallConv::TryGetCallingConventionFromUnmanagedCallersOnly(_In_ MethodDesc* CaTypeCtor caEntryPoint(SERIALIZATION_TYPE_STRING); namedArgs[1].Init("EntryPoint", SERIALIZATION_TYPE_STRING, caEntryPoint); + CaTypeCtor caAssociatedSourceType(SERIALIZATION_TYPE_TYPE); + namedArgs[2].Init("AssociatedSourceType", SERIALIZATION_TYPE_TYPE, caAssociatedSourceType); + InlineFactory, 4> caValueArrayFactory; Assembly* assembly = pMD->GetLoaderModule()->GetAssembly(); IfFailThrow(CustomAttribute::ParseArgumentValues( diff --git a/src/mono/mono/metadata/marshal.c b/src/mono/mono/metadata/marshal.c index 39d522bb570c6f..821ac6322f6d4f 100644 --- a/src/mono/mono/metadata/marshal.c +++ b/src/mono/mono/metadata/marshal.c @@ -3474,7 +3474,7 @@ mono_marshal_set_callconv_from_unmanaged_callers_only_attribute (MonoMethod *met } if (attr != NULL) { - MonoDecodeCustomAttr *decoded_args = mono_reflection_create_custom_attr_data_args_noalloc (mono_defaults.corlib, attr->ctor, attr->data, attr->data_size, error); + MonoDecodeCustomAttr *decoded_args = mono_reflection_create_custom_attr_data_args_noalloc (m_class_get_image (method->klass), attr->ctor, attr->data, attr->data_size, error); mono_error_assert_ok (error); for (int i = 0; i < decoded_args->named_args_num; ++i) { if (decoded_args->named_args_info [i].field && !strcmp (decoded_args->named_args_info [i].field->name, "CallConvs")) { diff --git a/src/tests/Interop/UnmanagedCallersOnlyBasic/UnmanagedCallersOnlyBasicTest.cs b/src/tests/Interop/UnmanagedCallersOnlyBasic/UnmanagedCallersOnlyBasicTest.cs index ffbafe2bc1669e..eaf36d4dfd3125 100644 --- a/src/tests/Interop/UnmanagedCallersOnlyBasic/UnmanagedCallersOnlyBasicTest.cs +++ b/src/tests/Interop/UnmanagedCallersOnlyBasic/UnmanagedCallersOnlyBasicTest.cs @@ -45,6 +45,12 @@ public static int ManagedDoubleCallback(int n) return DoubleImpl(n); } + [UnmanagedCallersOnly(AssociatedSourceType = typeof(UnmanagedCallersOnlyBasicTest))] + public static int ManagedDoubleCallback_AssociatedSourceType(int n) + { + return DoubleImpl(n); + } + [ActiveIssue("https://github.com/dotnet/runtime/issues/64127", typeof(PlatformDetection), nameof(PlatformDetection.PlatformDoesNotSupportNativeTestAssets))] [ActiveIssue("Needs coreclr build", typeof(PlatformDetection), nameof(PlatformDetection.IsMonoFULLAOT))] [ActiveIssue("needs triage", TestPlatforms.Android)] @@ -60,7 +66,21 @@ public static void TestUnmanagedCallersOnlyValid() Assert.Equal(expected, UnmanagedCallersOnlyDll.CallManagedProc((IntPtr)(delegate* unmanaged)&ManagedDoubleCallback, n)); } - [UnmanagedCallersOnly(CallConvs = [typeof(CallConvStdcall)])] + [ActiveIssue("https://github.com/dotnet/runtime/issues/64127", typeof(PlatformDetection), nameof(PlatformDetection.PlatformDoesNotSupportNativeTestAssets))] + [ActiveIssue("Needs coreclr build", typeof(PlatformDetection), nameof(PlatformDetection.IsMonoFULLAOT))] + [ActiveIssue("needs triage", TestPlatforms.Android)] + [ActiveIssue("needs triage", TestPlatforms.iOS | TestPlatforms.tvOS | TestPlatforms.MacCatalyst)] + [Fact] + public static void TestUnmanagedCallersOnlyValid_AssociatedSourceType() + { + Console.WriteLine($"Running {nameof(TestUnmanagedCallersOnlyValid_AssociatedSourceType)}..."); + + int n = 12345; + int expected = DoubleImpl(n); + Assert.Equal(expected, ((delegate* unmanaged)&ManagedDoubleCallback_AssociatedSourceType)(n)); + } + + [UnmanagedCallersOnly(CallConvs = [typeof(CallConvStdcall)])] public static int ManagedDoubleCallback_Stdcall(int n) { return DoubleImpl(n);