From ad03955be542a6ff2501481df676ce3d9e0f427f Mon Sep 17 00:00:00 2001 From: Marek Safar Date: Fri, 25 Jan 2019 02:00:33 +0100 Subject: [PATCH] Move Marshal to shared partition (#22146) * Move Marshal to shared partition * Moved code optimizations * Cosmetic changes * Avoid duplicate arguments checks bys shipping Encoding.UTF8.GetString --- .../System.Private.CoreLib.csproj | 3 +- .../shared/System.Private.CoreLib.Shared.projitems | 7 + .../InteropServices/ComEventsHelpers.NoCom.cs | 21 + .../Runtime/InteropServices/Marshal.NoCom.cs} | 18 +- .../System/Runtime/InteropServices/Marshal.Unix.cs | 11 + .../Runtime/InteropServices/Marshal.Windows.cs | 23 + .../System/Runtime/InteropServices/Marshal.cs | 698 +++++++++++++++++++ .../{Marshal.cs => Marshal.CoreCLR.cs} | 749 +-------------------- 8 files changed, 765 insertions(+), 765 deletions(-) create mode 100644 src/System.Private.CoreLib/shared/System/Runtime/InteropServices/ComEventsHelpers.NoCom.cs rename src/System.Private.CoreLib/{src/System/Runtime/InteropServices/NonPortable.cs => shared/System/Runtime/InteropServices/Marshal.NoCom.cs} (91%) create mode 100644 src/System.Private.CoreLib/shared/System/Runtime/InteropServices/Marshal.Unix.cs create mode 100644 src/System.Private.CoreLib/shared/System/Runtime/InteropServices/Marshal.Windows.cs create mode 100644 src/System.Private.CoreLib/shared/System/Runtime/InteropServices/Marshal.cs rename src/System.Private.CoreLib/src/System/Runtime/InteropServices/{Marshal.cs => Marshal.CoreCLR.cs} (62%) diff --git a/src/System.Private.CoreLib/System.Private.CoreLib.csproj b/src/System.Private.CoreLib/System.Private.CoreLib.csproj index e293399..62adef5 100644 --- a/src/System.Private.CoreLib/System.Private.CoreLib.csproj +++ b/src/System.Private.CoreLib/System.Private.CoreLib.csproj @@ -253,9 +253,8 @@ - + - diff --git a/src/System.Private.CoreLib/shared/System.Private.CoreLib.Shared.projitems b/src/System.Private.CoreLib/shared/System.Private.CoreLib.Shared.projitems index 7640d41..26eabe8 100644 --- a/src/System.Private.CoreLib/shared/System.Private.CoreLib.Shared.projitems +++ b/src/System.Private.CoreLib/shared/System.Private.CoreLib.Shared.projitems @@ -626,6 +626,7 @@ + @@ -991,12 +992,17 @@ + + + + + @@ -1099,6 +1105,7 @@ + diff --git a/src/System.Private.CoreLib/shared/System/Runtime/InteropServices/ComEventsHelpers.NoCom.cs b/src/System.Private.CoreLib/shared/System/Runtime/InteropServices/ComEventsHelpers.NoCom.cs new file mode 100644 index 0000000..7b29d6f --- /dev/null +++ b/src/System.Private.CoreLib/shared/System/Runtime/InteropServices/ComEventsHelpers.NoCom.cs @@ -0,0 +1,21 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Runtime.InteropServices.ComTypes; + +namespace System.Runtime.InteropServices +{ + public static class ComEventsHelper + { + public static void Combine(object rcw, Guid iid, int dispid, Delegate d) + { + throw new PlatformNotSupportedException(SR.PlatformNotSupported_ComInterop); + } + + public static Delegate Remove(object rcw, Guid iid, int dispid, Delegate d) + { + throw new PlatformNotSupportedException(SR.PlatformNotSupported_ComInterop); + } + } +} diff --git a/src/System.Private.CoreLib/src/System/Runtime/InteropServices/NonPortable.cs b/src/System.Private.CoreLib/shared/System/Runtime/InteropServices/Marshal.NoCom.cs similarity index 91% rename from src/System.Private.CoreLib/src/System/Runtime/InteropServices/NonPortable.cs rename to src/System.Private.CoreLib/shared/System/Runtime/InteropServices/Marshal.NoCom.cs index 590a551..7eda97b 100644 --- a/src/System.Private.CoreLib/src/System/Runtime/InteropServices/NonPortable.cs +++ b/src/System.Private.CoreLib/shared/System/Runtime/InteropServices/Marshal.NoCom.cs @@ -2,8 +2,6 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -// Dummy implementations of non-portable interop methods that just throw PlatformNotSupportedException - using System.Reflection; using System.Runtime.InteropServices.ComTypes; @@ -13,7 +11,7 @@ namespace System.Runtime.InteropServices { public static int GetHRForException(Exception e) { - return (e != null) ? e.HResult : 0; + return e?.HResult ?? 0; } public static int AddRef(IntPtr pUnk) @@ -35,7 +33,6 @@ namespace System.Runtime.InteropServices public static void CleanupUnusedObjectsInCurrentContext() { - return; } public static IntPtr CreateAggregatedObject(IntPtr pOuter, T o) @@ -202,17 +199,4 @@ namespace System.Runtime.InteropServices throw new PlatformNotSupportedException(SR.PlatformNotSupported_ComInterop); } } - - public static class ComEventsHelper - { - public static void Combine(object rcw, Guid iid, int dispid, Delegate d) - { - throw new PlatformNotSupportedException(SR.PlatformNotSupported_ComInterop); - } - - public static Delegate Remove(object rcw, Guid iid, int dispid, Delegate d) - { - throw new PlatformNotSupportedException(SR.PlatformNotSupported_ComInterop); - } - } } diff --git a/src/System.Private.CoreLib/shared/System/Runtime/InteropServices/Marshal.Unix.cs b/src/System.Private.CoreLib/shared/System/Runtime/InteropServices/Marshal.Unix.cs new file mode 100644 index 0000000..930baf9 --- /dev/null +++ b/src/System.Private.CoreLib/shared/System/Runtime/InteropServices/Marshal.Unix.cs @@ -0,0 +1,11 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +namespace System.Runtime.InteropServices +{ + public static partial class Marshal + { + private static bool IsWin32Atom(IntPtr ptr) => false; + } +} \ No newline at end of file diff --git a/src/System.Private.CoreLib/shared/System/Runtime/InteropServices/Marshal.Windows.cs b/src/System.Private.CoreLib/shared/System/Runtime/InteropServices/Marshal.Windows.cs new file mode 100644 index 0000000..7ea4d3a --- /dev/null +++ b/src/System.Private.CoreLib/shared/System/Runtime/InteropServices/Marshal.Windows.cs @@ -0,0 +1,23 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +namespace System.Runtime.InteropServices +{ + public static partial class Marshal + { + // Win32 has the concept of Atoms, where a pointer can either be a pointer + // or an int. If it's less than 64K, this is guaranteed to NOT be a + // pointer since the bottom 64K bytes are reserved in a process' page table. + // We should be careful about deallocating this stuff. Extracted to + // a function to avoid C# problems with lack of support for IntPtr. + // We have 2 of these methods for slightly different semantics for NULL. + private static bool IsWin32Atom(IntPtr ptr) + { + const long HIWORDMASK = unchecked((long)0xffffffffffff0000L); + + long lPtr = (long)ptr; + return 0 == (lPtr & HIWORDMASK); + } + } +} \ No newline at end of file diff --git a/src/System.Private.CoreLib/shared/System/Runtime/InteropServices/Marshal.cs b/src/System.Private.CoreLib/shared/System/Runtime/InteropServices/Marshal.cs new file mode 100644 index 0000000..dd59b03 --- /dev/null +++ b/src/System.Private.CoreLib/shared/System/Runtime/InteropServices/Marshal.cs @@ -0,0 +1,698 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Security; +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Text; +using Microsoft.Win32; + +using Internal.Runtime.CompilerServices; + +namespace System.Runtime.InteropServices +{ + /// + /// This class contains methods that are mainly used to marshal between unmanaged + /// and managed types. + /// + public static partial class Marshal + { + /// + /// The default character size for the system. This is always 2 because + /// the framework only runs on UTF-16 systems. + /// + public static readonly int SystemDefaultCharSize = 2; + + /// + /// The max DBCS character size for the system. + /// + public static readonly int SystemMaxDBCSCharSize = GetSystemMaxDBCSCharSize(); + + public static unsafe string PtrToStringAnsi(IntPtr ptr) + { + if (ptr == IntPtr.Zero || IsWin32Atom(ptr)) + { + return null; + } + + return new string((sbyte*)ptr); + } + + public static unsafe string PtrToStringAnsi(IntPtr ptr, int len) + { + if (ptr == IntPtr.Zero) + { + throw new ArgumentNullException(nameof(ptr)); + } + if (len < 0) + { + throw new ArgumentException(null, nameof(len)); + } + + return new string((sbyte*)ptr, 0, len); + } + + public static unsafe string PtrToStringUni(IntPtr ptr) + { + if (ptr == IntPtr.Zero || IsWin32Atom(ptr)) + { + return null; + } + + return new string((char*)ptr); + } + + public static unsafe string PtrToStringUni(IntPtr ptr, int len) + { + if (ptr == IntPtr.Zero) + { + throw new ArgumentNullException(nameof(ptr)); + } + if (len < 0) + { + throw new ArgumentException(SR.ArgumentOutOfRange_NeedNonNegNum, nameof(len)); + } + + return new string((char*)ptr, 0, len); + } + + public static string PtrToStringAuto(IntPtr ptr, int len) + { + // Ansi platforms are no longer supported + return PtrToStringUni(ptr, len); + } + + public static string PtrToStringAuto(IntPtr ptr) + { + // Ansi platforms are no longer supported + return PtrToStringUni(ptr); + } + + public static unsafe string PtrToStringUTF8(IntPtr ptr) + { + if (ptr == IntPtr.Zero) + { + return null; + } + + int nbBytes = string.strlen((byte*)ptr); + return string.CreateStringFromEncoding((byte*)ptr, nbBytes, Encoding.UTF8); + } + + public static unsafe string PtrToStringUTF8(IntPtr ptr, int byteLen) + { + if (byteLen < 0) + { + throw new ArgumentOutOfRangeException(nameof(byteLen), SR.ArgumentOutOfRange_NeedNonNegNum); + } + + if (ptr == IntPtr.Zero || IsWin32Atom(ptr)) + { + return null; + } + + return string.CreateStringFromEncoding((byte*)ptr, byteLen, Encoding.UTF8); + } + + public static int SizeOf(object structure) + { + if (structure == null) + { + throw new ArgumentNullException(nameof(structure)); + } + + return SizeOfHelper(structure.GetType(), throwIfNotMarshalable: true); + } + + public static int SizeOf(T structure) + { + if (structure == null) + { + throw new ArgumentNullException(nameof(structure)); + } + + return SizeOfHelper(structure.GetType(), throwIfNotMarshalable: true); + } + + public static int SizeOf(Type t) + { + if (t == null) + { + throw new ArgumentNullException(nameof(t)); + } + if (!t.IsRuntimeImplemented()) + { + throw new ArgumentException(SR.Argument_MustBeRuntimeType, nameof(t)); + } + if (t.IsGenericType) + { + throw new ArgumentException(SR.Argument_NeedNonGenericType, nameof(t)); + } + + return SizeOfHelper(t, throwIfNotMarshalable: true); + } + + public static int SizeOf() => SizeOf(typeof(T)); + + public static IntPtr OffsetOf(string fieldName) => OffsetOf(typeof(T), fieldName); + + public static void Copy(int[] source, int startIndex, IntPtr destination, int length) + { + CopyToNative(source, startIndex, destination, length); + } + + public static void Copy(char[] source, int startIndex, IntPtr destination, int length) + { + CopyToNative(source, startIndex, destination, length); + } + + public static void Copy(short[] source, int startIndex, IntPtr destination, int length) + { + CopyToNative(source, startIndex, destination, length); + } + + public static void Copy(long[] source, int startIndex, IntPtr destination, int length) + { + CopyToNative(source, startIndex, destination, length); + } + + public static void Copy(float[] source, int startIndex, IntPtr destination, int length) + { + CopyToNative(source, startIndex, destination, length); + } + + public static void Copy(double[] source, int startIndex, IntPtr destination, int length) + { + CopyToNative(source, startIndex, destination, length); + } + + public static void Copy(byte[] source, int startIndex, IntPtr destination, int length) + { + CopyToNative(source, startIndex, destination, length); + } + + public static void Copy(IntPtr[] source, int startIndex, IntPtr destination, int length) + { + CopyToNative(source, startIndex, destination, length); + } + + private static unsafe void CopyToNative(T[] source, int startIndex, IntPtr destination, int length) + { + if (source == null) + throw new ArgumentNullException(nameof(source)); + if (destination == IntPtr.Zero) + throw new ArgumentNullException(nameof(destination)); + + // The rest of the argument validation is done by CopyTo + + new Span(source, startIndex, length).CopyTo(new Span((void*)destination, length)); + } + + public static void Copy(IntPtr source, int[] destination, int startIndex, int length) + { + CopyToManaged(source, destination, startIndex, length); + } + + public static void Copy(IntPtr source, char[] destination, int startIndex, int length) + { + CopyToManaged(source, destination, startIndex, length); + } + + public static void Copy(IntPtr source, short[] destination, int startIndex, int length) + { + CopyToManaged(source, destination, startIndex, length); + } + + public static void Copy(IntPtr source, long[] destination, int startIndex, int length) + { + CopyToManaged(source, destination, startIndex, length); + } + + public static void Copy(IntPtr source, float[] destination, int startIndex, int length) + { + CopyToManaged(source, destination, startIndex, length); + } + + public static void Copy(IntPtr source, double[] destination, int startIndex, int length) + { + CopyToManaged(source, destination, startIndex, length); + } + + public static void Copy(IntPtr source, byte[] destination, int startIndex, int length) + { + CopyToManaged(source, destination, startIndex, length); + } + + public static void Copy(IntPtr source, IntPtr[] destination, int startIndex, int length) + { + CopyToManaged(source, destination, startIndex, length); + } + + private static unsafe void CopyToManaged(IntPtr source, T[] destination, int startIndex, int length) + { + if (source == IntPtr.Zero) + throw new ArgumentNullException(nameof(source)); + if (destination == null) + throw new ArgumentNullException(nameof(destination)); + if (startIndex < 0) + throw new ArgumentOutOfRangeException(nameof(startIndex), SR.ArgumentOutOfRange_StartIndex); + if (length < 0) + throw new ArgumentOutOfRangeException(nameof(length), SR.ArgumentOutOfRange_NeedNonNegNum); + + // The rest of the argument validation is done by CopyTo + + new Span((void*)source, length).CopyTo(new Span(destination, startIndex, length)); + } + + public static unsafe byte ReadByte(IntPtr ptr, int ofs) + { + try + { + byte* addr = (byte*)ptr + ofs; + return *addr; + } + catch (NullReferenceException) + { + // this method is documented to throw AccessViolationException on any AV + throw new AccessViolationException(); + } + } + + public static byte ReadByte(IntPtr ptr) => ReadByte(ptr, 0); + + public static unsafe short ReadInt16(IntPtr ptr, int ofs) + { + try + { + byte* addr = (byte*)ptr + ofs; + if ((unchecked((int)addr) & 0x1) == 0) + { + // aligned read + return *((short*)addr); + } + else + { + return Unsafe.ReadUnaligned(addr); + } + } + catch (NullReferenceException) + { + // this method is documented to throw AccessViolationException on any AV + throw new AccessViolationException(); + } + } + + public static short ReadInt16(IntPtr ptr) => ReadInt16(ptr, 0); + + public static unsafe int ReadInt32(IntPtr ptr, int ofs) + { + try + { + byte* addr = (byte*)ptr + ofs; + if ((unchecked((int)addr) & 0x3) == 0) + { + // aligned read + return *((int*)addr); + } + else + { + return Unsafe.ReadUnaligned(addr); + } + } + catch (NullReferenceException) + { + // this method is documented to throw AccessViolationException on any AV + throw new AccessViolationException(); + } + } + + public static int ReadInt32(IntPtr ptr) => ReadInt32(ptr, 0); + + public static IntPtr ReadIntPtr(object ptr, int ofs) + { +#if BIT64 + return (IntPtr)ReadInt64(ptr, ofs); +#else // 32 + return (IntPtr)ReadInt32(ptr, ofs); +#endif + } + + public static IntPtr ReadIntPtr(IntPtr ptr, int ofs) + { +#if BIT64 + return (IntPtr)ReadInt64(ptr, ofs); +#else // 32 + return (IntPtr)ReadInt32(ptr, ofs); +#endif + } + + public static IntPtr ReadIntPtr(IntPtr ptr) => ReadIntPtr(ptr, 0); + + public static unsafe long ReadInt64(IntPtr ptr, int ofs) + { + try + { + byte* addr = (byte*)ptr + ofs; + if ((unchecked((int)addr) & 0x7) == 0) + { + // aligned read + return *((long*)addr); + } + else + { + return Unsafe.ReadUnaligned(addr); + } + } + catch (NullReferenceException) + { + // this method is documented to throw AccessViolationException on any AV + throw new AccessViolationException(); + } + } + + public static long ReadInt64(IntPtr ptr) => ReadInt64(ptr, 0); + + public static unsafe void WriteByte(IntPtr ptr, int ofs, byte val) + { + try + { + byte* addr = (byte*)ptr + ofs; + *addr = val; + } + catch (NullReferenceException) + { + // this method is documented to throw AccessViolationException on any AV + throw new AccessViolationException(); + } + } + + public static void WriteByte(IntPtr ptr, byte val) => WriteByte(ptr, 0, val); + + public static unsafe void WriteInt16(IntPtr ptr, int ofs, short val) + { + try + { + byte* addr = (byte*)ptr + ofs; + if ((unchecked((int)addr) & 0x1) == 0) + { + // aligned write + *((short*)addr) = val; + } + else + { + Unsafe.WriteUnaligned(addr, val); + } + } + catch (NullReferenceException) + { + // this method is documented to throw AccessViolationException on any AV + throw new AccessViolationException(); + } + } + + public static void WriteInt16(IntPtr ptr, short val) => WriteInt16(ptr, 0, val); + + public static void WriteInt16(IntPtr ptr, int ofs, char val) => WriteInt16(ptr, ofs, (short)val); + + public static void WriteInt16([In, Out]object ptr, int ofs, char val) => WriteInt16(ptr, ofs, (short)val); + + public static void WriteInt16(IntPtr ptr, char val) => WriteInt16(ptr, 0, (short)val); + + public static unsafe void WriteInt32(IntPtr ptr, int ofs, int val) + { + try + { + byte* addr = (byte*)ptr + ofs; + if ((unchecked((int)addr) & 0x3) == 0) + { + // aligned write + *((int*)addr) = val; + } + else + { + Unsafe.WriteUnaligned(addr, val); + } + } + catch (NullReferenceException) + { + // this method is documented to throw AccessViolationException on any AV + throw new AccessViolationException(); + } + } + + public static void WriteInt32(IntPtr ptr, int val) => WriteInt32(ptr, 0, val); + + public static void WriteIntPtr(IntPtr ptr, int ofs, IntPtr val) + { +#if BIT64 + WriteInt64(ptr, ofs, (long)val); +#else // 32 + WriteInt32(ptr, ofs, (int)val); +#endif + } + + public static void WriteIntPtr(object ptr, int ofs, IntPtr val) + { +#if BIT64 + WriteInt64(ptr, ofs, (long)val); +#else // 32 + WriteInt32(ptr, ofs, (int)val); +#endif + } + + public static void WriteIntPtr(IntPtr ptr, IntPtr val) => WriteIntPtr(ptr, 0, val); + + public static unsafe void WriteInt64(IntPtr ptr, int ofs, long val) + { + try + { + byte* addr = (byte*)ptr + ofs; + if ((unchecked((int)addr) & 0x7) == 0) + { + // aligned write + *((long*)addr) = val; + } + else + { + Unsafe.WriteUnaligned(addr, val); + } + } + catch (NullReferenceException) + { + // this method is documented to throw AccessViolationException on any AV + throw new AccessViolationException(); + } + } + + public static void WriteInt64(IntPtr ptr, long val) => WriteInt64(ptr, 0, val); + + public static void Prelink(MethodInfo m) + { + if (m == null) + { + throw new ArgumentNullException(nameof(m)); + } + + PrelinkCore(m); + } + + public static void PrelinkAll(Type c) + { + if (c == null) + { + throw new ArgumentNullException(nameof(c)); + } + + MethodInfo[] mi = c.GetMethods(); + if (mi != null) + { + for (int i = 0; i < mi.Length; i++) + { + Prelink(mi[i]); + } + } + } + + public static void StructureToPtr(T structure, IntPtr ptr, bool fDeleteOld) + { + StructureToPtr((object)structure, ptr, fDeleteOld); + } + + /// + /// Creates a new instance of "structuretype" and marshals data from a + /// native memory block to it. + /// + public static object PtrToStructure(IntPtr ptr, Type structureType) + { + if (ptr == IntPtr.Zero) + { + return null; + } + + if (structureType == null) + { + throw new ArgumentNullException(nameof(structureType)); + } + if (structureType.IsGenericType) + { + throw new ArgumentException(SR.Argument_NeedNonGenericType, nameof(structureType)); + } + if (!structureType.IsRuntimeImplemented()) + { + throw new ArgumentException(SR.Argument_MustBeRuntimeType, nameof(structureType)); + } + + return PtrToStructureHelper(ptr, structureType); + } + + /// + /// Marshals data from a native memory block to a preallocated structure class. + /// + public static void PtrToStructure(IntPtr ptr, object structure) + { + PtrToStructureHelper(ptr, structure, allowValueClasses: false); + } + + public static void PtrToStructure(IntPtr ptr, T structure) + { + PtrToStructure(ptr, (object)structure); + } + + public static T PtrToStructure(IntPtr ptr) => (T)PtrToStructure(ptr, typeof(T)); + + public static void DestroyStructure(IntPtr ptr) => DestroyStructure(ptr, typeof(T)); + + /// + /// Converts the HRESULT to a CLR exception. + /// + public static Exception GetExceptionForHR(int errorCode) => GetExceptionForHR(errorCode, IntPtr.Zero); + + public static Exception GetExceptionForHR(int errorCode, IntPtr errorInfo) + { + if (errorCode >= 0) + { + return null; + } + + return GetExceptionForHRInternal(errorCode, errorInfo); + } + + public static IntPtr SecureStringToBSTR(SecureString s) + { + if (s == null) + { + throw new ArgumentNullException(nameof(s)); + } + + return s.MarshalToBSTR(); + } + + public static IntPtr SecureStringToCoTaskMemAnsi(SecureString s) + { + if (s == null) + { + throw new ArgumentNullException(nameof(s)); + } + + return s.MarshalToString(globalAlloc: false, unicode: false); + } + + public static IntPtr SecureStringToCoTaskMemUnicode(SecureString s) + { + if (s == null) + { + throw new ArgumentNullException(nameof(s)); + } + + return s.MarshalToString(globalAlloc: false, unicode: true); + } + + public static IntPtr SecureStringToGlobalAllocAnsi(SecureString s) + { + if (s == null) + { + throw new ArgumentNullException(nameof(s)); + } + + return s.MarshalToString(globalAlloc: true, unicode: false); + } + + public static IntPtr SecureStringToGlobalAllocUnicode(SecureString s) + { + if (s == null) + { + throw new ArgumentNullException(nameof(s)); + } + + return s.MarshalToString(globalAlloc: true, unicode: true); ; + } + + /// + /// Generates a GUID for the specified type. If the type has a GUID in the + /// metadata then it is returned otherwise a stable guid is generated based + /// on the fully qualified name of the type. + /// + public static Guid GenerateGuidForType(Type type) + { + if (type == null) + { + throw new ArgumentNullException(nameof(type)); + } + if (!type.IsRuntimeImplemented()) + { + throw new ArgumentException(SR.Argument_MustBeRuntimeType, nameof(type)); + } + + return type.GUID; + } + + public static Delegate GetDelegateForFunctionPointer(IntPtr ptr, Type t) + { + if (ptr == IntPtr.Zero) + { + throw new ArgumentNullException(nameof(ptr)); + } + if (t == null) + { + throw new ArgumentNullException(nameof(t)); + } + if (!t.IsRuntimeImplemented()) + { + throw new ArgumentException(SR.Argument_MustBeRuntimeType, nameof(t)); + } + if (t.IsGenericType) + { + throw new ArgumentException(SR.Argument_NeedNonGenericType, nameof(t)); + } + + Type c = t.BaseType; + if (c != typeof(Delegate) && c != typeof(MulticastDelegate)) + { + throw new ArgumentException(SR.Arg_MustBeDelegate, nameof(t)); + } + + return GetDelegateForFunctionPointerInternal(ptr, t); + } + + public static TDelegate GetDelegateForFunctionPointer(IntPtr ptr) + { + return (TDelegate)(object)GetDelegateForFunctionPointer(ptr, typeof(TDelegate)); + } + + public static IntPtr GetFunctionPointerForDelegate(Delegate d) + { + if (d == null) + { + throw new ArgumentNullException(nameof(d)); + } + + return GetFunctionPointerForDelegateInternal(d); + } + + public static IntPtr GetFunctionPointerForDelegate(TDelegate d) + { + return GetFunctionPointerForDelegate((Delegate)(object)d); + } + } +} \ No newline at end of file diff --git a/src/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshal.cs b/src/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshal.CoreCLR.cs similarity index 62% rename from src/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshal.cs rename to src/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshal.CoreCLR.cs index 5e1396b..4881b27 100644 --- a/src/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshal.cs +++ b/src/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshal.CoreCLR.cs @@ -38,36 +38,6 @@ namespace System.Runtime.InteropServices private const int LMEM_FIXED = 0; private const int LMEM_MOVEABLE = 2; -#if !FEATURE_PAL - private const long HiWordMask = unchecked((long)0xffffffffffff0000L); -#endif //!FEATURE_PAL - - // Win32 has the concept of Atoms, where a pointer can either be a pointer - // or an int. If it's less than 64K, this is guaranteed to NOT be a - // pointer since the bottom 64K bytes are reserved in a process' page table. - // We should be careful about deallocating this stuff. Extracted to - // a function to avoid C# problems with lack of support for IntPtr. - // We have 2 of these methods for slightly different semantics for NULL. - private static bool IsWin32Atom(IntPtr ptr) - { -#if FEATURE_PAL - return false; -#else - long lPtr = (long)ptr; - return 0 == (lPtr & HiWordMask); -#endif - } - - /// - /// The default character size for the system. This is always 2 because - /// the framework only runs on UTF-16 systems. - /// - public static readonly int SystemDefaultCharSize = 2; - - /// - /// The max DBCS character size for the system. - /// - public static readonly int SystemMaxDBCSCharSize = GetSystemMaxDBCSCharSize(); /// /// Helper method to retrieve the system's maximum DBCS character size. @@ -75,145 +45,6 @@ namespace System.Runtime.InteropServices [MethodImpl(MethodImplOptions.InternalCall)] private static extern int GetSystemMaxDBCSCharSize(); - public static unsafe string PtrToStringAnsi(IntPtr ptr) - { - if (IntPtr.Zero == ptr) - { - return null; - } - else if (IsWin32Atom(ptr)) - { - return null; - } - - int nb = string.strlen((byte*)ptr); - if (nb == 0) - { - return string.Empty; - } - - return new string((sbyte*)ptr); - } - - public static unsafe string PtrToStringAnsi(IntPtr ptr, int len) - { - if (ptr == IntPtr.Zero) - { - throw new ArgumentNullException(nameof(ptr)); - } - if (len < 0) - { - throw new ArgumentException(null, nameof(len)); - } - - return new string((sbyte*)ptr, 0, len); - } - - public static unsafe string PtrToStringUni(IntPtr ptr, int len) - { - if (ptr == IntPtr.Zero) - { - throw new ArgumentNullException(nameof(ptr)); - } - if (len < 0) - { - throw new ArgumentException(SR.ArgumentOutOfRange_NeedNonNegNum, nameof(len)); - } - - return new string((char*)ptr, 0, len); - } - - public static string PtrToStringAuto(IntPtr ptr, int len) - { - // Ansi platforms are no longer supported - return PtrToStringUni(ptr, len); - } - - public static unsafe string PtrToStringUni(IntPtr ptr) - { - if (IntPtr.Zero == ptr) - { - return null; - } - else if (IsWin32Atom(ptr)) - { - return null; - } - - return new string((char*)ptr); - } - - public static string PtrToStringAuto(IntPtr ptr) - { - // Ansi platforms are no longer supported - return PtrToStringUni(ptr); - } - - public static unsafe string PtrToStringUTF8(IntPtr ptr) - { - if (IntPtr.Zero == ptr) - { - return null; - } - - int nbBytes = string.strlen((byte*)ptr); - return PtrToStringUTF8(ptr, nbBytes); - } - - public static unsafe string PtrToStringUTF8(IntPtr ptr, int byteLen) - { - if (byteLen < 0) - { - throw new ArgumentOutOfRangeException(nameof(byteLen), SR.ArgumentOutOfRange_NeedNonNegNum); - } - else if (IntPtr.Zero == ptr) - { - return null; - } - else if (IsWin32Atom(ptr)) - { - return null; - } - else if (byteLen == 0) - { - return string.Empty; - } - - return Encoding.UTF8.GetString((byte*)ptr, byteLen); - } - - public static int SizeOf(object structure) - { - if (structure == null) - { - throw new ArgumentNullException(nameof(structure)); - } - - return SizeOfHelper(structure.GetType(), true); - } - - public static int SizeOf(T structure) => SizeOf((object)structure); - - public static int SizeOf(Type t) - { - if (t == null) - { - throw new ArgumentNullException(nameof(t)); - } - if (!(t is RuntimeType)) - { - throw new ArgumentException(SR.Argument_MustBeRuntimeType, nameof(t)); - } - if (t.IsGenericType) - { - throw new ArgumentException(SR.Argument_NeedNonGenericType, nameof(t)); - } - - return SizeOfHelper(t, throwIfNotMarshalable: true); - } - - public static int SizeOf() => SizeOf(typeof(T)); - [MethodImpl(MethodImplOptions.InternalCall)] internal static extern int SizeOfHelper(Type t, bool throwIfNotMarshalable); @@ -238,8 +69,6 @@ namespace System.Runtime.InteropServices return OffsetOfHelper(rtField); } - public static IntPtr OffsetOf(string fieldName) => OffsetOf(typeof(T), fieldName); - [MethodImpl(MethodImplOptions.InternalCall)] private static extern IntPtr OffsetOfHelper(IRuntimeFieldInfo f); @@ -266,265 +95,26 @@ namespace System.Runtime.InteropServices return (IntPtr)((byte*)pRawData + (uint)index * (nuint)Unsafe.SizeOf()); } - public static void Copy(int[] source, int startIndex, IntPtr destination, int length) - { - CopyToNative(source, startIndex, destination, length); - } - - public static void Copy(char[] source, int startIndex, IntPtr destination, int length) - { - CopyToNative(source, startIndex, destination, length); - } - - public static void Copy(short[] source, int startIndex, IntPtr destination, int length) - { - CopyToNative(source, startIndex, destination, length); - } - - public static void Copy(long[] source, int startIndex, IntPtr destination, int length) - { - CopyToNative(source, startIndex, destination, length); - } - - public static void Copy(float[] source, int startIndex, IntPtr destination, int length) - { - CopyToNative(source, startIndex, destination, length); - } - - public static void Copy(double[] source, int startIndex, IntPtr destination, int length) - { - CopyToNative(source, startIndex, destination, length); - } - - public static void Copy(byte[] source, int startIndex, IntPtr destination, int length) - { - CopyToNative(source, startIndex, destination, length); - } - - public static void Copy(IntPtr[] source, int startIndex, IntPtr destination, int length) - { - CopyToNative(source, startIndex, destination, length); - } - - private static unsafe void CopyToNative(T[] source, int startIndex, IntPtr destination, int length) - { - if (source == null) - throw new ArgumentNullException(nameof(source)); - if (destination == IntPtr.Zero) - throw new ArgumentNullException(nameof(destination)); - - // The rest of the argument validation is done by CopyTo - - new Span(source, startIndex, length).CopyTo(new Span((void*)destination, length)); - } - - public static void Copy(IntPtr source, int[] destination, int startIndex, int length) - { - CopyToManaged(source, destination, startIndex, length); - } - - public static void Copy(IntPtr source, char[] destination, int startIndex, int length) - { - CopyToManaged(source, destination, startIndex, length); - } - - public static void Copy(IntPtr source, short[] destination, int startIndex, int length) - { - CopyToManaged(source, destination, startIndex, length); - } - - public static void Copy(IntPtr source, long[] destination, int startIndex, int length) - { - CopyToManaged(source, destination, startIndex, length); - } - - public static void Copy(IntPtr source, float[] destination, int startIndex, int length) - { - CopyToManaged(source, destination, startIndex, length); - } - - public static void Copy(IntPtr source, double[] destination, int startIndex, int length) - { - CopyToManaged(source, destination, startIndex, length); - } - - public static void Copy(IntPtr source, byte[] destination, int startIndex, int length) - { - CopyToManaged(source, destination, startIndex, length); - } - - public static void Copy(IntPtr source, IntPtr[] destination, int startIndex, int length) - { - CopyToManaged(source, destination, startIndex, length); - } - - private static unsafe void CopyToManaged(IntPtr source, T[] destination, int startIndex, int length) - { - if (source == IntPtr.Zero) - throw new ArgumentNullException(nameof(source)); - if (destination == null) - throw new ArgumentNullException(nameof(destination)); - if (startIndex < 0) - throw new ArgumentOutOfRangeException(nameof(startIndex), SR.ArgumentOutOfRange_StartIndex); - if (length < 0) - throw new ArgumentOutOfRangeException(nameof(length), SR.ArgumentOutOfRange_NeedNonNegNum); - - // The rest of the argument validation is done by CopyTo - - new Span((void*)source, length).CopyTo(new Span(destination, startIndex, length)); - } - public static byte ReadByte(object ptr, int ofs) { return ReadValueSlow(ptr, ofs, (IntPtr nativeHome, int offset) => ReadByte(nativeHome, offset)); } - public static unsafe byte ReadByte(IntPtr ptr, int ofs) - { - try - { - byte* addr = (byte*)ptr + ofs; - return *addr; - } - catch (NullReferenceException) - { - // this method is documented to throw AccessViolationException on any AV - throw new AccessViolationException(); - } - } - - public static byte ReadByte(IntPtr ptr) => ReadByte(ptr, 0); - public static short ReadInt16(object ptr, int ofs) { return ReadValueSlow(ptr, ofs, (IntPtr nativeHome, int offset) => ReadInt16(nativeHome, offset)); } - public static unsafe short ReadInt16(IntPtr ptr, int ofs) - { - try - { - byte* addr = (byte*)ptr + ofs; - if ((unchecked((int)addr) & 0x1) == 0) - { - // aligned read - return *((short*)addr); - } - else - { - // unaligned read - short val; - byte* valPtr = (byte*)&val; - valPtr[0] = addr[0]; - valPtr[1] = addr[1]; - return val; - } - } - catch (NullReferenceException) - { - // this method is documented to throw AccessViolationException on any AV - throw new AccessViolationException(); - } - } - - public static short ReadInt16(IntPtr ptr) => ReadInt16(ptr, 0); - public static int ReadInt32(object ptr, int ofs) { return ReadValueSlow(ptr, ofs, (IntPtr nativeHome, int offset) => ReadInt32(nativeHome, offset)); } - public static unsafe int ReadInt32(IntPtr ptr, int ofs) - { - try - { - byte* addr = (byte*)ptr + ofs; - if ((unchecked((int)addr) & 0x3) == 0) - { - // aligned read - return *((int*)addr); - } - else - { - // unaligned read - int val; - byte* valPtr = (byte*)&val; - valPtr[0] = addr[0]; - valPtr[1] = addr[1]; - valPtr[2] = addr[2]; - valPtr[3] = addr[3]; - return val; - } - } - catch (NullReferenceException) - { - // this method is documented to throw AccessViolationException on any AV - throw new AccessViolationException(); - } - } - - public static int ReadInt32(IntPtr ptr) => ReadInt32(ptr, 0); - - public static IntPtr ReadIntPtr(object ptr, int ofs) - { -#if BIT64 - return (IntPtr)ReadInt64(ptr, ofs); -#else // 32 - return (IntPtr)ReadInt32(ptr, ofs); -#endif - } - - public static IntPtr ReadIntPtr(IntPtr ptr, int ofs) - { -#if BIT64 - return (IntPtr)ReadInt64(ptr, ofs); -#else // 32 - return (IntPtr)ReadInt32(ptr, ofs); -#endif - } - - public static IntPtr ReadIntPtr(IntPtr ptr) => ReadIntPtr(ptr, 0); - public static long ReadInt64([MarshalAs(UnmanagedType.AsAny), In] object ptr, int ofs) { return ReadValueSlow(ptr, ofs, (IntPtr nativeHome, int offset) => ReadInt64(nativeHome, offset)); } - public static unsafe long ReadInt64(IntPtr ptr, int ofs) - { - try - { - byte* addr = (byte*)ptr + ofs; - if ((unchecked((int)addr) & 0x7) == 0) - { - // aligned read - return *((long*)addr); - } - else - { - // unaligned read - long val; - byte* valPtr = (byte*)&val; - valPtr[0] = addr[0]; - valPtr[1] = addr[1]; - valPtr[2] = addr[2]; - valPtr[3] = addr[3]; - valPtr[4] = addr[4]; - valPtr[5] = addr[5]; - valPtr[6] = addr[6]; - valPtr[7] = addr[7]; - return val; - } - } - catch (NullReferenceException) - { - // this method is documented to throw AccessViolationException on any AV - throw new AccessViolationException(); - } - } - - public static long ReadInt64(IntPtr ptr) => ReadInt64(ptr, 0); - //==================================================================== // Read value from marshaled object (marshaled using AsAny) // It's quite slow and can return back dangling pointers @@ -560,157 +150,26 @@ namespace System.Runtime.InteropServices } } - public static unsafe void WriteByte(IntPtr ptr, int ofs, byte val) - { - try - { - byte* addr = (byte*)ptr + ofs; - *addr = val; - } - catch (NullReferenceException) - { - // this method is documented to throw AccessViolationException on any AV - throw new AccessViolationException(); - } - } - public static void WriteByte(object ptr, int ofs, byte val) { WriteValueSlow(ptr, ofs, val, (IntPtr nativeHome, int offset, byte value) => WriteByte(nativeHome, offset, value)); } - public static void WriteByte(IntPtr ptr, byte val) => WriteByte(ptr, 0, val); - - public static unsafe void WriteInt16(IntPtr ptr, int ofs, short val) - { - try - { - byte* addr = (byte*)ptr + ofs; - if ((unchecked((int)addr) & 0x1) == 0) - { - // aligned write - *((short*)addr) = val; - } - else - { - // unaligned write - byte* valPtr = (byte*)&val; - addr[0] = valPtr[0]; - addr[1] = valPtr[1]; - } - } - catch (NullReferenceException) - { - // this method is documented to throw AccessViolationException on any AV - throw new AccessViolationException(); - } - } - public static void WriteInt16(object ptr, int ofs, short val) { WriteValueSlow(ptr, ofs, val, (IntPtr nativeHome, int offset, short value) => Marshal.WriteInt16(nativeHome, offset, value)); } - public static void WriteInt16(IntPtr ptr, short val) => WriteInt16(ptr, 0, val); - - public static void WriteInt16(IntPtr ptr, int ofs, char val) => WriteInt16(ptr, ofs, (short)val); - - public static void WriteInt16([In, Out]object ptr, int ofs, char val) => WriteInt16(ptr, ofs, (short)val); - - public static void WriteInt16(IntPtr ptr, char val) => WriteInt16(ptr, 0, (short)val); - - public static unsafe void WriteInt32(IntPtr ptr, int ofs, int val) - { - try - { - byte* addr = (byte*)ptr + ofs; - if ((unchecked((int)addr) & 0x3) == 0) - { - // aligned write - *((int*)addr) = val; - } - else - { - // unaligned write - byte* valPtr = (byte*)&val; - addr[0] = valPtr[0]; - addr[1] = valPtr[1]; - addr[2] = valPtr[2]; - addr[3] = valPtr[3]; - } - } - catch (NullReferenceException) - { - // this method is documented to throw AccessViolationException on any AV - throw new AccessViolationException(); - } - } - public static void WriteInt32(object ptr, int ofs, int val) { WriteValueSlow(ptr, ofs, val, (IntPtr nativeHome, int offset, int value) => Marshal.WriteInt32(nativeHome, offset, value)); } - public static void WriteInt32(IntPtr ptr, int val) => WriteInt32(ptr, 0, val); - - public static void WriteIntPtr(IntPtr ptr, int ofs, IntPtr val) - { -#if BIT64 - WriteInt64(ptr, ofs, (long)val); -#else // 32 - WriteInt32(ptr, ofs, (int)val); -#endif - } - - public static void WriteIntPtr(object ptr, int ofs, IntPtr val) - { -#if BIT64 - WriteInt64(ptr, ofs, (long)val); -#else // 32 - WriteInt32(ptr, ofs, (int)val); -#endif - } - - public static void WriteIntPtr(IntPtr ptr, IntPtr val) => WriteIntPtr(ptr, 0, val); - - public static unsafe void WriteInt64(IntPtr ptr, int ofs, long val) - { - try - { - byte* addr = (byte*)ptr + ofs; - if ((unchecked((int)addr) & 0x7) == 0) - { - // aligned write - *((long*)addr) = val; - } - else - { - // unaligned write - byte* valPtr = (byte*)&val; - addr[0] = valPtr[0]; - addr[1] = valPtr[1]; - addr[2] = valPtr[2]; - addr[3] = valPtr[3]; - addr[4] = valPtr[4]; - addr[5] = valPtr[5]; - addr[6] = valPtr[6]; - addr[7] = valPtr[7]; - } - } - catch (NullReferenceException) - { - // this method is documented to throw AccessViolationException on any AV - throw new AccessViolationException(); - } - } - public static void WriteInt64(object ptr, int ofs, long val) { WriteValueSlow(ptr, ofs, val, (IntPtr nativeHome, int offset, long value) => Marshal.WriteInt64(nativeHome, offset, value)); } - public static void WriteInt64(IntPtr ptr, long val) => WriteInt64(ptr, 0, val); - /// /// Write value into marshaled object (marshaled using AsAny) and propagate the /// value back. This is quite slow and can return back dangling pointers. It is @@ -764,12 +223,8 @@ namespace System.Runtime.InteropServices return (dwLastError & 0x0000FFFF) | unchecked((int)0x80070000); } - public static void Prelink(MethodInfo m) + private static void PrelinkCore(MethodInfo m) { - if (m == null) - { - throw new ArgumentNullException(nameof(m)); - } if (!(m is RuntimeMethodInfo rmi)) { throw new ArgumentException(SR.Argument_MustBeRuntimeMethodInfo, nameof(m)); @@ -781,23 +236,6 @@ namespace System.Runtime.InteropServices [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)] private static extern void InternalPrelink(IRuntimeMethodInfo m); - public static void PrelinkAll(Type c) - { - if (c == null) - { - throw new ArgumentNullException(nameof(c)); - } - - MethodInfo[] mi = c.GetMethods(); - if (mi != null) - { - for (int i = 0; i < mi.Length; i++) - { - Prelink(mi[i]); - } - } - } - [MethodImpl(MethodImplOptions.InternalCall)] public static extern /* struct _EXCEPTION_POINTERS* */ IntPtr GetExceptionPointers(); @@ -812,55 +250,14 @@ namespace System.Runtime.InteropServices [MethodImpl(MethodImplOptions.InternalCall), ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)] public static extern void StructureToPtr(object structure, IntPtr ptr, bool fDeleteOld); - public static void StructureToPtr(T structure, IntPtr ptr, bool fDeleteOld) - { - StructureToPtr((object)structure, ptr, fDeleteOld); - } - - /// - /// Marshals data from a native memory block to a preallocated structure class. - /// - public static void PtrToStructure(IntPtr ptr, object structure) - { - PtrToStructureHelper(ptr, structure, allowValueClasses: false); - } - - public static void PtrToStructure(IntPtr ptr, T structure) - { - PtrToStructure(ptr, (object)structure); - } - - /// - /// Creates a new instance of "structuretype" and marshals data from a - /// native memory block to it. - /// - public static object PtrToStructure(IntPtr ptr, Type structureType) + private static object PtrToStructureHelper(IntPtr ptr, Type structureType) { - if (ptr == IntPtr.Zero) - { - return null; - } - - if (structureType == null) - { - throw new ArgumentNullException(nameof(structureType)); - } - if (structureType.IsGenericType) - { - throw new ArgumentException(SR.Argument_NeedNonGenericType, nameof(structureType)); - } - if (!(structureType.UnderlyingSystemType is RuntimeType rt)) - { - throw new ArgumentException(SR.Arg_MustBeType, nameof(structureType)); - } - + var rt = (RuntimeType)structureType; object structure = rt.CreateInstanceDefaultCtor(publicOnly: false, skipCheckThis: false, fillCache: false, wrapExceptions: true); PtrToStructureHelper(ptr, structure, allowValueClasses: true); return structure; } - public static T PtrToStructure(IntPtr ptr) => (T)PtrToStructure(ptr, typeof(T)); - /// /// Helper function to copy a pointer into a preallocated structure. /// @@ -874,8 +271,6 @@ namespace System.Runtime.InteropServices [MethodImpl(MethodImplOptions.InternalCall)] public static extern void DestroyStructure(IntPtr ptr, Type structuretype); - public static void DestroyStructure(IntPtr ptr) => DestroyStructure(ptr, typeof(T)); - [MethodImpl(MethodImplOptions.InternalCall)] internal static extern bool IsPinnable(object obj); @@ -926,27 +321,6 @@ namespace System.Runtime.InteropServices [MethodImpl(MethodImplOptions.InternalCall)] internal static extern void ThrowExceptionForHRInternal(int errorCode, IntPtr errorInfo); - /// - /// Converts the HRESULT to a CLR exception. - /// - public static Exception GetExceptionForHR(int errorCode) - { - if (errorCode >= 0) - { - return null; - } - - return GetExceptionForHRInternal(errorCode, IntPtr.Zero); - } - public static Exception GetExceptionForHR(int errorCode, IntPtr errorInfo) - { - if (errorCode >= 0) - { - return null; - } - - return GetExceptionForHRInternal(errorCode, errorInfo); - } [MethodImpl(MethodImplOptions.InternalCall)] internal static extern Exception GetExceptionForHRInternal(int errorCode, IntPtr errorInfo); @@ -1572,25 +946,6 @@ namespace System.Runtime.InteropServices #endif // FEATURE_COMINTEROP /// - /// Generates a GUID for the specified type. If the type has a GUID in the - /// metadata then it is returned otherwise a stable guid is generated based - /// on the fully qualified name of the type. - /// - public static Guid GenerateGuidForType(Type type) - { - if (type == null) - { - throw new ArgumentNullException(nameof(type)); - } - if (!(type is RuntimeType)) - { - throw new ArgumentException(SR.Argument_MustBeRuntimeType, nameof(type)); - } - - return type.GUID; - } - - /// /// This method generates a PROGID for the specified type. If the type has /// a PROGID in the metadata then it is returned otherwise a stable PROGID /// is generated based on the fully qualified name of the type. @@ -1683,89 +1038,11 @@ namespace System.Runtime.InteropServices #endif // FEATURE_COMINTEROP - public static Delegate GetDelegateForFunctionPointer(IntPtr ptr, Type t) - { - if (ptr == IntPtr.Zero) - { - throw new ArgumentNullException(nameof(ptr)); - } - if (t == null) - { - throw new ArgumentNullException(nameof(t)); - } - if (!(t is RuntimeType)) - { - throw new ArgumentException(SR.Argument_MustBeRuntimeType, nameof(t)); - } - if (t.IsGenericType) - { - throw new ArgumentException(SR.Argument_NeedNonGenericType, nameof(t)); - } - - Type c = t.BaseType; - if (c == null || (c != typeof(Delegate) && c != typeof(MulticastDelegate))) - { - throw new ArgumentException(SR.Arg_MustBeDelegate, nameof(t)); - } - - return GetDelegateForFunctionPointerInternal(ptr, t); - } - - public static TDelegate GetDelegateForFunctionPointer(IntPtr ptr) - { - return (TDelegate)(object)GetDelegateForFunctionPointer(ptr, typeof(TDelegate)); - } - [MethodImpl(MethodImplOptions.InternalCall)] internal static extern Delegate GetDelegateForFunctionPointerInternal(IntPtr ptr, Type t); - public static IntPtr GetFunctionPointerForDelegate(Delegate d) - { - if (d == null) - { - throw new ArgumentNullException(nameof(d)); - } - - return GetFunctionPointerForDelegateInternal(d); - } - - public static IntPtr GetFunctionPointerForDelegate(TDelegate d) - { - return GetFunctionPointerForDelegate((Delegate)(object)d); - } - [MethodImpl(MethodImplOptions.InternalCall)] internal static extern IntPtr GetFunctionPointerForDelegateInternal(Delegate d); - - public static IntPtr SecureStringToBSTR(SecureString s) - { - if (s == null) - { - throw new ArgumentNullException(nameof(s)); - } - - return s.MarshalToBSTR(); - } - - public static IntPtr SecureStringToCoTaskMemAnsi(SecureString s) - { - if (s == null) - { - throw new ArgumentNullException(nameof(s)); - } - - return s.MarshalToString(globalAlloc: false, unicode: false); - } - - public static IntPtr SecureStringToCoTaskMemUnicode(SecureString s) - { - if (s == null) - { - throw new ArgumentNullException(nameof(s)); - } - - return s.MarshalToString(globalAlloc: false, unicode: true); - } public static void ZeroFreeBSTR(IntPtr s) { @@ -1807,26 +1084,6 @@ namespace System.Runtime.InteropServices FreeCoTaskMem(s); } - public static IntPtr SecureStringToGlobalAllocAnsi(SecureString s) - { - if (s == null) - { - throw new ArgumentNullException(nameof(s)); - } - - return s.MarshalToString(globalAlloc: true, unicode: false); - } - - public static IntPtr SecureStringToGlobalAllocUnicode(SecureString s) - { - if (s == null) - { - throw new ArgumentNullException(nameof(s)); - } - - return s.MarshalToString(globalAlloc: true, unicode: true); ; - } - public unsafe static void ZeroFreeGlobalAllocAnsi(IntPtr s) { if (s == IntPtr.Zero) -- 2.7.4