Repository: dotnet/runtime
File: src/coreclr/System.Private.CoreLib/src/System/StubHelpers.cs (C#)

Code before:
            ConvertContentsToManaged(pMarshalState, ObjectHandleOnStack.Create(ref managedHome), pNativeHome);
        }

        [LibraryImport(RuntimeHelpers.QCall, EntryPoint = "MngdSafeArrayMarshaler_ConvertContentsToManaged")]
        private static partial void ConvertContentsToManaged(IntPtr pMarshalState, ObjectHandleOnStack pManagedHome, IntPtr pNativeHome);

#pragma warning disable IDE0060 // Remove unused parameter. These APIs need to match a the shape of a "managed" marshaler.
        internal static void ClearNative(IntPtr pMarshalState, in object pManagedHome, IntPtr pNativeHome)
        {
            ClearNative(pMarshalState, pNativeHome);
        }
#pragma warning restore IDE0060

        [LibraryImport(RuntimeHelpers.QCall, EntryPoint = "MngdSafeArrayMarshaler_ClearNative")]
        private static partial void ClearNative(IntPtr pMarshalState, IntPtr pNativeHome);
    }  // class MngdSafeArrayMarshaler
#endif // FEATURE_COMINTEROP

    internal static unsafe partial class MngdRefCustomMarshaler
    {
        [UnmanagedCallersOnly]
        internal static void ConvertContentsToNative(ObjectHandleOnStack marshaler, ObjectHandleOnStack pManagedHome, IntPtr* pNativeHome, ObjectHandleOnStack exception)
        {
            try
            {
                ICustomMarshaler customMarshaler = (ICustomMarshaler)marshaler.Value!;
                object managedHome = pManagedHome.Value!;
                ConvertContentsToNative(customMarshaler, in managedHome, pNativeHome);
            }
            catch (Exception ex)
            {
                exception.Value = ex;
            }
        }

        internal static void ConvertContentsToNative(ICustomMarshaler marshaler, in object pManagedHome, IntPtr* pNativeHome)
        {
            // COMPAT: We never pass null to MarshalManagedToNative.
            if (pManagedHome is null)
            {
                *pNativeHome = IntPtr.Zero;
                return;
            }

            *pNativeHome = marshaler.MarshalManagedToNative(pManagedHome);
        }

        [UnmanagedCallersOnly]
        internal static void ConvertContentsToManaged(ObjectHandleOnStack marshaler, ObjectHandleOnStack pManagedHome, IntPtr* pNativeHome, ObjectHandleOnStack exception)
        {
            try

Review comment (suggestion):
This is adding `(ICustomMarshaler)` cast that was not there before. We may want to use `Unsafe.As` in situations like this. It probably does not matter a lot in this case, just as a general pattern.  

Code after:
            ConvertContentsToManaged(pMarshalState, ObjectHandleOnStack.Create(ref managedHome), pNativeHome);
        }

        [LibraryImport(RuntimeHelpers.QCall, EntryPoint = "MngdSafeArrayMarshaler_ConvertContentsToManaged")]
        private static partial void ConvertContentsToManaged(IntPtr pMarshalState, ObjectHandleOnStack pManagedHome, IntPtr pNativeHome);

#pragma warning disable IDE0060 // Remove unused parameter. These APIs need to match a the shape of a "managed" marshaler.
        internal static void ClearNative(IntPtr pMarshalState, in object pManagedHome, IntPtr pNativeHome)
        {
            ClearNative(pMarshalState, pNativeHome);
        }
#pragma warning restore IDE0060

        [LibraryImport(RuntimeHelpers.QCall, EntryPoint = "MngdSafeArrayMarshaler_ClearNative")]
        private static partial void ClearNative(IntPtr pMarshalState, IntPtr pNativeHome);
    }  // class MngdSafeArrayMarshaler
#endif // FEATURE_COMINTEROP

    internal static unsafe partial class MngdRefCustomMarshaler
    {
        [UnmanagedCallersOnly]
        internal static void ConvertContentsToNative(ICustomMarshaler* pMarshaler, object* pManagedHome, IntPtr* pNativeHome, Exception* pException)
        {
            try
            {
                ConvertContentsToNative(*pMarshaler, in *pManagedHome, pNativeHome);
            }
            catch (Exception ex)
            {
                *pException = ex;
            }
        }

        internal static void ConvertContentsToNative(ICustomMarshaler marshaler, in object pManagedHome, IntPtr* pNativeHome)
        {
            // COMPAT: We never pass null to MarshalManagedToNative.
            if (pManagedHome is null)
            {
                *pNativeHome = IntPtr.Zero;
                return;
            }

            *pNativeHome = marshaler.MarshalManagedToNative(pManagedHome);
        }

        [UnmanagedCallersOnly]
        internal static void ConvertContentsToManaged(ICustomMarshaler* pMarshaler, object* pManagedHome, IntPtr* pNativeHome, Exception* pException)
        {
            try
            {
                ConvertContentsToManaged(*pMarshaler, ref *pManagedHome, pNativeHome);