diff options
author | Jan Kotas <jkotas@microsoft.com> | 2016-01-04 03:49:17 +0300 |
---|---|---|
committer | Jan Kotas <jkotas@microsoft.com> | 2016-01-04 03:49:17 +0300 |
commit | 0a2ae2c2fe664b17207fd96305005aa81f3df4cb (patch) | |
tree | 1bab81bd2b7ea262ca5a52449ebfd498c3e535ad /src/System.Private.CoreLib | |
parent | 6ff9b777ca204e31055bad3e34ac74942b6c6a7d (diff) |
Remove System.Private.CoreLib interop dependency on delegate marshalling
System.Private.CoreLib interop dependency on delegate marshalling is a hidden cyclic dependency between System.Private.CoreLib and System.Private.Interop. This change is breaking the cycle by using NativeCallable methods instead. It actually simplified the code as well.
[tfs-changeset: 1560833]
Diffstat (limited to 'src/System.Private.CoreLib')
5 files changed, 33 insertions, 255 deletions
diff --git a/src/System.Private.CoreLib/src/Interop/Interop.manual.cs b/src/System.Private.CoreLib/src/Interop/Interop.manual.cs index 4ccf5bcd4..7b1b9bf9b 100644 --- a/src/System.Private.CoreLib/src/Interop/Interop.manual.cs +++ b/src/System.Private.CoreLib/src/Interop/Interop.manual.cs @@ -438,6 +438,9 @@ internal partial class Interop [DllImport("api-ms-win-core-localization-l1-2-0.dll", CharSet = CharSet.Unicode)] internal static extern int GetLocaleInfoEx(string lpLocaleName, uint LCType, IntPtr lpLCData, int cchData); + [DllImport("api-ms-win-core-localization-l1-2-1.dll")] + internal extern static bool EnumSystemLocalesEx(IntPtr lpLocaleEnumProcEx, uint dwFlags, IntPtr lParam, IntPtr lpReserved); + [DllImport("api-ms-win-core-heap-l1-1-0.dll")] internal extern static IntPtr GetProcessHeap(); @@ -780,151 +783,6 @@ internal partial class Interop return (IntPtr)(-2); } - // - // Wrappers for encoding - // - internal const uint ERROR_INSUFFICIENT_BUFFER = 122; - - [DllImport("api-ms-win-core-string-l1-1-0.dll")] - [MethodImpl(MethodImplOptions.NoInlining)] - internal extern unsafe static int WideCharToMultiByte( - int CodePage, - uint dwFlags, - char* lpWideCharStr, - int cchWideChar, - byte* lpMultiByteStr, - int cbMultiByte, - byte* lpDefaultChar, - int* lpUsedDefaultChar); - - [DllImport("api-ms-win-core-string-l1-1-0.dll")] - [MethodImpl(MethodImplOptions.NoInlining)] - internal extern unsafe static int MultiByteToWideChar( - int CodePage, - uint dwFlags, - byte* lpMultiByteStr, - int cbMultiByte, - char* lpWideCharStr, - int cchWideChar); - - [DllImport("api-ms-win-core-localization-l1-2-0.dll")] - [MethodImpl(MethodImplOptions.NoInlining)] - internal extern unsafe static int GetCPInfoExW(int codepage, uint flag, byte* pCodePageInfo); - - private static unsafe int GetByteCount(int codepage, Char* pChars, int count) - { - if (count == 0) return 0; - - int result = WideCharToMultiByte(codepage, 0, pChars, count, null, 0, null, null); - if (result <= 0) - throw new ArgumentException(SR.Argument_InvalidCharSequenceNoIndex); - return result; - } - - internal static unsafe int GetByteCount(int codepage, char[] chars, int index, int count) - { - fixed (char* pChars = &chars[index]) - { - return GetByteCount(codepage, pChars, count); - } - } - - internal static unsafe int GetByteCount(int codepage, string s) - { - fixed (char* pChars = s) - { - return GetByteCount(codepage, pChars, s.Length); - } - } - - private static unsafe int GetBytes(int codepage, char* pChars, int charCount, byte* pBytes, int byteCount) - { - if (charCount == 0) - return 0; - - int result = WideCharToMultiByte(codepage, 0, pChars, charCount, pBytes, byteCount, null, null); - if (result <= 0) - { - uint lastErroro = Interop.mincore.GetLastError(); - if (lastErroro == ERROR_INSUFFICIENT_BUFFER) - throw new ArgumentOutOfRangeException(SR.Argument_EncodingConversionOverflowBytes); - throw new ArgumentException(SR.Argument_InvalidCharSequenceNoIndex); - } - return result; - } - - internal unsafe static int GetBytes(int codepage, char[] chars, int index, int count, byte[] bytes, int byteIndex) - { - fixed (byte* pBytes = &bytes[byteIndex]) - fixed (char* pChars = &chars[index]) - { - return GetBytes(codepage, pChars, count, pBytes, bytes.Length - byteIndex); - } - } - - internal unsafe static int GetBytes(int codepage, string s, int charIndex, int charCount, byte[] bytes, int byteIndex) - { - fixed (byte* pBytes = &bytes[byteIndex]) - fixed (char* pChars = s) - { - return GetBytes(codepage, pChars + charIndex, charCount, pBytes, bytes.Length - byteIndex); - } - } - - internal static unsafe int GetCharCount(int codepage, byte* pBytes, int count) - { - if (count == 0) return 0; - - int result = MultiByteToWideChar(codepage, 0, pBytes, count, null, 0); - if (result <= 0) - throw new ArgumentException(SR.Argument_InvalidCharSequenceNoIndex); - return result; - } - - internal static unsafe int GetCharCount(int codepage, byte[] bytes, int index, int count) - { - fixed (byte* pBytes = &bytes[index]) - { - return GetCharCount(codepage, pBytes, count); - } - } - - internal static unsafe int GetChars(int codepage, byte* bytes, int byteCount, char* chars, int charsCount) - { - if (byteCount == 0) - return 0; - - int result = MultiByteToWideChar(codepage, 0, bytes, byteCount, chars, charsCount); - if (result <= 0) - { - uint lastErroro = Interop.mincore.GetLastError(); - if (lastErroro == ERROR_INSUFFICIENT_BUFFER) - throw new ArgumentOutOfRangeException(SR.Argument_EncodingConversionOverflowChars); - throw new ArgumentException(SR.Argument_InvalidCharSequenceNoIndex); - } - return result; - } - - internal static unsafe int GetChars(int codepage, byte[] bytes, int byteIndex, int byteCount, char[] chars, int charIndex) - { - if (byteCount == 0) - return 0; - - fixed (byte* pBytes = &bytes[byteIndex]) - fixed (char* pChars = &chars[charIndex]) - { - int result = MultiByteToWideChar(codepage, 0, pBytes, byteCount, pChars, chars.Length - charIndex); - if (result <= 0) - { - uint lastErroro = Interop.mincore.GetLastError(); - if (lastErroro == ERROR_INSUFFICIENT_BUFFER) - throw new ArgumentOutOfRangeException(SR.Argument_EncodingConversionOverflowChars); - throw new ArgumentException(SR.Argument_InvalidCharSequenceNoIndex); - } - return result; - } - } - private readonly static System.Threading.WaitHandle s_sleepHandle = new System.Threading.ManualResetEvent(false); static internal void Sleep(uint milliseconds) { @@ -934,35 +792,6 @@ internal partial class Interop s_sleepHandle.WaitOne((int)milliseconds); } } - - internal partial class mincore_obsolete - { - [DllImport("api-ms-win-core-localization-l1-2-1.dll")] - internal extern static bool EnumSystemLocalesEx(EnumLocalesProcEx lpLocaleEnumProcEx, uint dwFlags, mincore_private.LParamCallbackContext lParam, IntPtr lpReserved); - - internal delegate bool EnumLocalesProcEx(IntPtr arg0, uint arg1, mincore_private.LParamCallbackContext arg2); - } - // declare the specialized callback context type, deriving from the CallbackContext type that MCG expects the class library to implement. - internal partial class mincore_private - { -#pragma warning disable 649 - internal class LParamCallbackContext : CallbackContext - { - // Put any user data to pass to the callback here. The user code being called back will get the instance of this class that was passed to the API originally. - internal IntPtr lParam; - } - - [DllImport("api-ms-win-core-localization-l2-1-0.dll", CharSet = CharSet.Unicode)] - internal extern static bool EnumCalendarInfoExEx(EnumCalendarInfoExExCallback pCalInfoEnumProcExEx, string lpLocaleName, uint Calendar, string lpReserved, uint CalType, mincore_private.LParamCallbackContext lParam); - - [DllImport("api-ms-win-core-localization-l2-1-0.dll", CharSet = CharSet.Unicode)] - internal extern static bool EnumTimeFormatsEx(EnumTimeFormatsProcEx lpTimeFmtEnumProcEx, string lpLocaleName, uint dwFlags, mincore_private.LParamCallbackContext lParam); - - internal delegate bool EnumCalendarInfoExExCallback(IntPtr arg0, uint arg1, IntPtr arg2, mincore_private.LParamCallbackContext arg3); - - // Unmanaged Function Pointer - Calling Convention StdCall - internal delegate bool EnumTimeFormatsProcEx(IntPtr arg0, mincore_private.LParamCallbackContext arg1); - } internal unsafe partial class WinRT { internal const int RPC_E_CHANGED_MODE = unchecked((int)0x80010106); diff --git a/src/System.Private.CoreLib/src/System.Private.CoreLib.csproj b/src/System.Private.CoreLib/src/System.Private.CoreLib.csproj index 58c437da1..418be30f1 100644 --- a/src/System.Private.CoreLib/src/System.Private.CoreLib.csproj +++ b/src/System.Private.CoreLib/src/System.Private.CoreLib.csproj @@ -354,7 +354,6 @@ <Compile Include="System\Runtime\GcSettings.cs" /> <Compile Include="System\Runtime\TypeLoaderExports.cs" /> <Compile Include="System\Runtime\InitializeFinalizerThread.cs" /> - <Compile Include="System\Runtime\InteropServices\CallbackContext.cs" /> <Compile Include="System\Runtime\InteropServices\ComVisibleAttribute.cs" /> <Compile Include="System\Runtime\InteropServices\DllImportAttribute.cs" /> <Compile Include="System\Runtime\InteropServices\GCHandle.cs" /> @@ -489,6 +488,7 @@ <Compile Condition="'$(IsProjectNLibrary)' == 'true'" Include="System\Environment.EnvironmentVariables.UWP.cs" /> <Compile Condition="'$(IsProjectNLibrary)' != 'true'" Include="System\Environment.EnvironmentVariables.Win32.cs" /> <Compile Include="..\..\Common\src\Interop\Windows\mincore\Interop.Environment.cs" /> + <Compile Include="..\..\Common\src\Interop\Windows\Interop.BOOL.cs" /> </ItemGroup> <ItemGroup> <!-- CORERT-TODO: Port to Unix --> diff --git a/src/System.Private.CoreLib/src/System/Globalization/CalendarData.Win32.cs b/src/System.Private.CoreLib/src/System/Globalization/CalendarData.Win32.cs index 7e8e3fabe..23731e935 100644 --- a/src/System.Private.CoreLib/src/System/Globalization/CalendarData.Win32.cs +++ b/src/System.Private.CoreLib/src/System/Globalization/CalendarData.Win32.cs @@ -156,15 +156,11 @@ namespace System.Globalization } GCHandle contextHandle = GCHandle.Alloc(data); - try { - Interop.mincore_private.EnumCalendarInfoExExCallback callback = new Interop.mincore_private.EnumCalendarInfoExExCallback(EnumCalendarsCallback); - Interop.mincore_private.LParamCallbackContext context = new Interop.mincore_private.LParamCallbackContext(); - context.lParam = (IntPtr)contextHandle; - // Now call the enumeration API. Work is done by our callback function - Interop.mincore_private.EnumCalendarInfoExEx(callback, localeName, ENUM_ALL_CALENDARS, null, CAL_ICALINTVALUE, context); + IntPtr callback = AddrofIntrinsics.AddrOf<Func<IntPtr, uint, IntPtr, IntPtr, Interop.BOOL>>(EnumCalendarsCallback); + Interop.mincore.EnumCalendarInfoExEx(callback, localeName, ENUM_ALL_CALENDARS, null, CAL_ICALINTVALUE, (IntPtr)contextHandle); } finally { @@ -338,9 +334,10 @@ namespace System.Globalization } // EnumCalendarInfoExEx callback itself. - private static unsafe bool EnumCalendarInfoCallback(IntPtr lpCalendarInfoString, uint calendar, IntPtr pReserved, Interop.mincore_private.LParamCallbackContext contextHandle) + [NativeCallable(CallingConvention = CallingConvention.StdCall)] + private static unsafe Interop.BOOL EnumCalendarInfoCallback(IntPtr lpCalendarInfoString, uint calendar, IntPtr pReserved, IntPtr lParam) { - EnumData context = (EnumData)((GCHandle)contextHandle.lParam).Target; + EnumData context = (EnumData)((GCHandle)lParam).Target; try { string calendarInfo = new string((char*)lpCalendarInfoString); @@ -349,11 +346,11 @@ namespace System.Globalization if (context.userOverride != calendarInfo) context.strings.Add(calendarInfo); - return true; + return Interop.BOOL.TRUE; } catch (Exception) { - return false; + return Interop.BOOL.FALSE; } } @@ -393,12 +390,9 @@ namespace System.Globalization GCHandle contextHandle = GCHandle.Alloc(context); try { - Interop.mincore_private.EnumCalendarInfoExExCallback callback = new Interop.mincore_private.EnumCalendarInfoExExCallback(EnumCalendarInfoCallback); - Interop.mincore_private.LParamCallbackContext ctx = new Interop.mincore_private.LParamCallbackContext(); - ctx.lParam = (IntPtr)contextHandle; - // Now call the enumeration API. Work is done by our callback function - Interop.mincore_private.EnumCalendarInfoExEx(callback, localeName, (uint)calendar, null, calType, ctx); + IntPtr callback = AddrofIntrinsics.AddrOf<Func<IntPtr, uint, IntPtr, IntPtr, Interop.BOOL>>(EnumCalendarInfoCallback); + Interop.mincore.EnumCalendarInfoExEx(callback, localeName, (uint)calendar, null, calType, (IntPtr)contextHandle); } finally { @@ -499,20 +493,21 @@ namespace System.Globalization public LowLevelList<int> calendars; // list of calendars found so far } - private static bool EnumCalendarsCallback(IntPtr lpCalendarInfoString, uint calendar, IntPtr reserved, Interop.mincore_private.LParamCallbackContext cxt) + [NativeCallable(CallingConvention = CallingConvention.StdCall)] + private static Interop.BOOL EnumCalendarsCallback(IntPtr lpCalendarInfoString, uint calendar, IntPtr reserved, IntPtr lParam) { - EnumCalendarsData context = (EnumCalendarsData)((GCHandle)cxt.lParam).Target; + EnumCalendarsData context = (EnumCalendarsData)((GCHandle)lParam).Target; try { // If we had a user override, check to make sure this differs if (context.userOverride != calendar) context.calendars.Add((int)calendar); - return true; + return Interop.BOOL.TRUE; } catch (Exception) { - return false; + return Interop.BOOL.FALSE; } } diff --git a/src/System.Private.CoreLib/src/System/Globalization/CultureData.Win32.cs b/src/System.Private.CoreLib/src/System/Globalization/CultureData.Win32.cs index 38327548b..d24b102e2 100644 --- a/src/System.Private.CoreLib/src/System/Globalization/CultureData.Win32.cs +++ b/src/System.Private.CoreLib/src/System/Globalization/CultureData.Win32.cs @@ -248,11 +248,8 @@ namespace System.Globalization GCHandle contextHandle = GCHandle.Alloc(context); try { - Interop.mincore_obsolete.EnumLocalesProcEx callback = new Interop.mincore_obsolete.EnumLocalesProcEx(EnumSystemLocalesProc); - Interop.mincore_private.LParamCallbackContext ctx = new Interop.mincore_private.LParamCallbackContext(); - ctx.lParam = (IntPtr)contextHandle; - - Interop.mincore_obsolete.EnumSystemLocalesEx(callback, LOCALE_SPECIFICDATA | LOCALE_SUPPLEMENTAL, ctx, IntPtr.Zero); + IntPtr callback = AddrofIntrinsics.AddrOf<Func<IntPtr, uint, IntPtr, Interop.BOOL>>(EnumSystemLocalesProc); + Interop.mincore.EnumSystemLocalesEx(callback, LOCALE_SPECIFICDATA | LOCALE_SUPPLEMENTAL, (IntPtr)contextHandle, IntPtr.Zero); } finally { @@ -474,9 +471,10 @@ namespace System.Globalization } // EnumSystemLocaleEx callback. - private static unsafe bool EnumSystemLocalesProc(IntPtr lpLocaleString, uint flags, Interop.mincore_private.LParamCallbackContext contextHandle) + [NativeCallable(CallingConvention = CallingConvention.StdCall)] + private static unsafe Interop.BOOL EnumSystemLocalesProc(IntPtr lpLocaleString, uint flags, IntPtr contextHandle) { - EnumLocaleData context = (EnumLocaleData)((GCHandle)contextHandle.lParam).Target; + EnumLocaleData context = (EnumLocaleData)((GCHandle)contextHandle).Target; try { string cultureName = new string((char*)lpLocaleString); @@ -484,14 +482,14 @@ namespace System.Globalization if (regionName != null && regionName.Equals(context.regionName, StringComparison.OrdinalIgnoreCase)) { context.cultureName = cultureName; - return false; // we found a match, then stop the enumeration + return Interop.BOOL.FALSE; // we found a match, then stop the enumeration } - return true; + return Interop.BOOL.TRUE; } catch (Exception) { - return false; + return Interop.BOOL.FALSE; } } @@ -502,18 +500,19 @@ namespace System.Globalization } // EnumTimeFormatsEx callback itself. - private static unsafe bool EnumTimeCallback(IntPtr lpTimeFormatString, Interop.mincore_private.LParamCallbackContext contextHandle) + [NativeCallable(CallingConvention = CallingConvention.StdCall)] + private static unsafe Interop.BOOL EnumTimeCallback(IntPtr lpTimeFormatString, IntPtr lParam) { - EnumData context = (EnumData)((GCHandle)contextHandle.lParam).Target; + EnumData context = (EnumData)((GCHandle)lParam).Target; try { context.strings.Add(new string((char*)lpTimeFormatString)); - return true; + return Interop.BOOL.TRUE; } catch (Exception) { - return false; + return Interop.BOOL.FALSE; } } @@ -526,15 +525,11 @@ namespace System.Globalization data.strings = new LowLevelList<string>(); GCHandle dataHandle = GCHandle.Alloc(data); - try { - Interop.mincore_private.EnumTimeFormatsProcEx callback = new Interop.mincore_private.EnumTimeFormatsProcEx(EnumTimeCallback); - Interop.mincore_private.LParamCallbackContext cxt = new Interop.mincore_private.LParamCallbackContext(); - cxt.lParam = (IntPtr)dataHandle; - // Now call the enumeration API. Work is done by our callback function - Interop.mincore_private.EnumTimeFormatsEx(callback, localeName, (uint)dwFlags, cxt); + IntPtr callback = AddrofIntrinsics.AddrOf<Func<IntPtr, IntPtr, Interop.BOOL>>(EnumTimeCallback); + Interop.mincore.EnumTimeFormatsEx(callback, localeName, (uint)dwFlags, (IntPtr)dataHandle); } finally { diff --git a/src/System.Private.CoreLib/src/System/Runtime/InteropServices/CallbackContext.cs b/src/System.Private.CoreLib/src/System/Runtime/InteropServices/CallbackContext.cs deleted file mode 100644 index 3b65278f5..000000000 --- a/src/System.Private.CoreLib/src/System/Runtime/InteropServices/CallbackContext.cs +++ /dev/null @@ -1,41 +0,0 @@ -// Copyright (c) Microsoft. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. - -namespace System.Runtime.InteropServices -{ - internal class CallbackContext : IDisposable - { - private Delegate _callbackMethod; - private GCHandle _selfGCHandle; - public virtual void Dispose() - { - _selfGCHandle.Free(); - } - public Delegate CallbackMethod - { - get - { - return _callbackMethod; - } - set - { - //Mcg.Helpers.Assert((m_callbackMethod == null)); - _callbackMethod = value; - } - } - public IntPtr GetContextHandle() - { - if ((_selfGCHandle.IsAllocated == false)) - { - _selfGCHandle = GCHandle.Alloc( - this, - GCHandleType.Normal); - } - return GCHandle.ToIntPtr(_selfGCHandle); - } - public static object GetObjectFromContextHandle(IntPtr contextHandle) - { - return GCHandle.FromIntPtr(contextHandle).Target; - } - } -} |