diff --git a/src/System.Private.CoreLib/Resources/Strings.resx b/src/System.Private.CoreLib/Resources/Strings.resx index b13bce230d56..9ba8ed8837e8 100644 --- a/src/System.Private.CoreLib/Resources/Strings.resx +++ b/src/System.Private.CoreLib/Resources/Strings.resx @@ -2428,7 +2428,10 @@ Unable to import a global method or field from a different module. - + + A Resolver is alerady Set for the Assembly. + + Cannot remove the last element from an empty collection. diff --git a/src/System.Private.CoreLib/src/System/Runtime/InteropServices/NativeLibrary.cs b/src/System.Private.CoreLib/src/System/Runtime/InteropServices/NativeLibrary.cs index 6b24cd79eab7..e6cee1fbab7d 100644 --- a/src/System.Private.CoreLib/src/System/Runtime/InteropServices/NativeLibrary.cs +++ b/src/System.Private.CoreLib/src/System/Runtime/InteropServices/NativeLibrary.cs @@ -9,6 +9,7 @@ using System.Runtime.ConstrainedExecution; using Win32Native = Microsoft.Win32.Win32Native; using System.Diagnostics; +using System.Threading; namespace System.Runtime.InteropServices { @@ -209,7 +210,8 @@ public static void SetDllImportResolver(Assembly assembly, DllImportResolver res if (s_nativeDllResolveMap == null) { - s_nativeDllResolveMap = new ConditionalWeakTable(); + Interlocked.CompareExchange(ref s_nativeDllResolveMap, + new ConditionalWeakTable(), null); } try @@ -219,7 +221,7 @@ public static void SetDllImportResolver(Assembly assembly, DllImportResolver res catch (ArgumentException e) { // ConditionalWealTable throws ArgumentException if the Key already exists - throw new InvalidOperationException("Resolver is alerady Set for the Assembly"); + throw new InvalidOperationException(SR.InvalidOperation_CannotRegisterSecondResolver); } } @@ -236,9 +238,12 @@ public static void SetDllImportResolver(Assembly assembly, DllImportResolver res internal static IntPtr LoadLibraryCallbackStub(string libraryName, Assembly assembly, bool hasDllImportSearchPathFlags, uint dllImportSearchPathFlags) { - DllImportResolver resolver; + if (s_nativeDllResolveMap == null) + { + return IntPtr.Zero; + } - if (!s_nativeDllResolveMap.TryGetValue(assembly, out resolver)) + if (!s_nativeDllResolveMap.TryGetValue(assembly, out DllImportResolver resolver)) { return IntPtr.Zero; } diff --git a/tests/src/Interop/NativeLibraryResolveCallBack/CallBackTests.cs b/tests/src/Interop/NativeLibraryResolveCallBack/CallBackTests.cs index 83deb6e49f03..67654203b4cd 100644 --- a/tests/src/Interop/NativeLibraryResolveCallBack/CallBackTests.cs +++ b/tests/src/Interop/NativeLibraryResolveCallBack/CallBackTests.cs @@ -27,19 +27,27 @@ public static int Main() throw new ArgumentException(); } - return NativeLibrary.Load("ResolveLib", asm, dllImportSearchPath); + return NativeLibrary.Load("ResolveLib", asm, null); }; DllImportResolver anotherResolver = (string libraryName, Assembly asm, DllImportSearchPath? dllImportSearchPath) => IntPtr.Zero; + try + { + NativeSum(10, 10); + Console.WriteLine("Exception expected: no callback registered yet"); + return 101; + } + catch (DllNotFoundException e) {} + try { NativeLibrary.SetDllImportResolver(null, resolver); - Console.WriteLine("Expected exception not thrown"); - return 101; + Console.WriteLine("Exception expected: assembly parameter null"); + return 102; } catch (ArgumentNullException e) { } @@ -47,8 +55,8 @@ public static int Main() { NativeLibrary.SetDllImportResolver(assembly, null); - Console.WriteLine("Expected exception not thrown"); - return 102; + Console.WriteLine("Exception expected: resolver parameter null"); + return 103; } catch (ArgumentNullException e) { } @@ -60,21 +68,21 @@ public static int Main() // Try to set another resolver on the same assembly. NativeLibrary.SetDllImportResolver(assembly, anotherResolver); - Console.WriteLine("Expected Exception not thrown"); - return 103; + Console.WriteLine("Exception expected: Trying to register second resolver"); + return 104; } catch (InvalidOperationException e) { } if (NativeSum(10, 10) != 20) { Console.WriteLine("Unexpected ReturnValue from NativeSum()"); - return 104; + return 105; } } catch (Exception e) { Console.WriteLine($"Unexpected exception: {e.ToString()} {e.Message}"); - return 105; + return 106; } return 100;