Move NativeLibrary to the shared partition (#24143)
authorMichal Strehovský <MichalStrehovsky@users.noreply.github.com>
Tue, 30 Apr 2019 02:16:10 +0000 (04:16 +0200)
committerJan Kotas <jkotas@microsoft.com>
Tue, 30 Apr 2019 02:16:10 +0000 (19:16 -0700)
I'm taking the LibraryNameVariation helper from System.Runtime.Loader for the ride as well because it's a general purpose probing logic that is useful in a managed implementation of NativeLibrary.

src/System.Private.CoreLib/System.Private.CoreLib.csproj
src/System.Private.CoreLib/shared/System.Private.CoreLib.Shared.projitems
src/System.Private.CoreLib/shared/System/Runtime/InteropServices/NativeLibrary.cs [moved from src/System.Private.CoreLib/src/System/Runtime/InteropServices/NativeLibrary.cs with 88% similarity]
src/System.Private.CoreLib/shared/System/Runtime/Loader/LibraryNameVariation.Unix.cs [new file with mode: 0644]
src/System.Private.CoreLib/shared/System/Runtime/Loader/LibraryNameVariation.Windows.cs [new file with mode: 0644]
src/System.Private.CoreLib/shared/System/Runtime/Loader/LibraryNameVariation.cs [new file with mode: 0644]
src/System.Private.CoreLib/src/System/Runtime/InteropServices/NativeLibrary.CoreCLR.cs [new file with mode: 0644]
src/System.Private.CoreLib/src/System/Runtime/Loader/AssemblyDependencyResolver.cs

index c012ba5..d97f405 100644 (file)
     <Compile Include="$(BclSourcesRoot)\System\Runtime\InteropServices\Expando\IExpando.cs" />
     <Compile Include="$(BclSourcesRoot)\System\Runtime\InteropServices\GCHandle.CoreCLR.cs" />
     <Compile Include="$(BclSourcesRoot)\System\Runtime\InteropServices\Marshal.CoreCLR.cs" />
-    <Compile Include="$(BclSourcesRoot)\System\Runtime\InteropServices\NativeLibrary.cs" />
+    <Compile Include="$(BclSourcesRoot)\System\Runtime\InteropServices\NativeLibrary.CoreCLR.cs" />
     <Compile Include="$(BclSourcesRoot)\System\Runtime\Loader\AssemblyDependencyResolver.cs" />
     <Compile Include="$(BclSourcesRoot)\System\Runtime\Loader\AssemblyLoadContext.CoreCLR.cs" />
     <Compile Include="$(BclSourcesRoot)\System\Runtime\Versioning\CompatibilitySwitch.cs" />
index 4562862..5337436 100644 (file)
     <Compile Include="$(MSBuildThisFileDirectory)System\Runtime\InteropServices\MemoryMarshal.cs" />
     <Compile Include="$(MSBuildThisFileDirectory)System\Runtime\InteropServices\MemoryMarshal.Fast.cs" />
     <Compile Include="$(MSBuildThisFileDirectory)System\Runtime\InteropServices\NativeCallableAttribute.cs" />
+    <Compile Include="$(MSBuildThisFileDirectory)System\Runtime\InteropServices\NativeLibrary.cs" />
     <Compile Include="$(MSBuildThisFileDirectory)System\Runtime\InteropServices\OptionalAttribute.cs" />
     <Compile Include="$(MSBuildThisFileDirectory)System\Runtime\InteropServices\OutAttribute.cs" />
     <Compile Include="$(MSBuildThisFileDirectory)System\Runtime\InteropServices\PreserveSigAttribute.cs" />
     <Compile Include="$(MSBuildThisFileDirectory)System\Runtime\Intrinsics\Vector256DebugView_1.cs" />
     <Compile Include="$(MSBuildThisFileDirectory)System\Runtime\Intrinsics\X86\Enums.cs" />
     <Compile Include="$(MSBuildThisFileDirectory)System\Runtime\Loader\AssemblyLoadContext.cs" Condition="'$(TargetsCoreRT)' != 'true'" />
+    <Compile Include="$(MSBuildThisFileDirectory)System\Runtime\Loader\LibraryNameVariation.cs" />
     <Compile Include="$(MSBuildThisFileDirectory)System\Runtime\Remoting\ObjectHandle.cs" />
     <Compile Include="$(MSBuildThisFileDirectory)System\Runtime\Serialization\DeserializationBlockedException.cs" />
     <Compile Include="$(MSBuildThisFileDirectory)System\Runtime\Serialization\DeserializationToken.cs" />
     <Compile Include="$(MSBuildThisFileDirectory)System\IO\PathInternal.Windows.cs" />
     <Compile Include="$(MSBuildThisFileDirectory)System\IO\DisableMediaInsertionPrompt.cs" />
     <Compile Include="$(MSBuildThisFileDirectory)System\PasteArguments.Windows.cs" />
+    <Compile Include="$(MSBuildThisFileDirectory)System\Runtime\Loader\LibraryNameVariation.Windows.cs" />
     <Compile Include="$(MSBuildThisFileDirectory)System\Runtime\MemoryFailPoint.Windows.cs" />
     <Compile Include="$(MSBuildThisFileDirectory)System\Runtime\InteropServices\Marshal.Windows.cs" Condition="'$(TargetsCoreRT)' != 'true'" />
     <Compile Include="$(MSBuildThisFileDirectory)System\Security\SecureString.Windows.cs" />
     <Compile Include="$(MSBuildThisFileDirectory)System\IO\PersistedFiles.Unix.cs" />
     <Compile Include="$(MSBuildThisFileDirectory)System\IO\PersistedFiles.Names.Unix.cs" />
     <Compile Include="$(MSBuildThisFileDirectory)System\PasteArguments.Unix.cs" />
+    <Compile Include="$(MSBuildThisFileDirectory)System\Runtime\Loader\LibraryNameVariation.Unix.cs" />
     <Compile Include="$(MSBuildThisFileDirectory)System\Runtime\MemoryFailPoint.Unix.cs" />
     <Compile Include="$(MSBuildThisFileDirectory)System\Runtime\InteropServices\Marshal.Unix.cs" Condition="'$(TargetsCoreRT)' != 'true'" />
     <Compile Include="$(MSBuildThisFileDirectory)System\Security\SecureString.Unix.cs" />
@@ -88,13 +88,12 @@ namespace System.Runtime.InteropServices
                 throw new ArgumentNullException(nameof(libraryName));
             if (assembly == null)
                 throw new ArgumentNullException(nameof(assembly));
-            if (!(assembly is RuntimeAssembly))
+            if (!assembly.IsRuntimeImplemented())
                 throw new ArgumentException(SR.Argument_MustBeRuntimeAssembly);
             
-            return LoadByName(libraryName, 
-                              ((RuntimeAssembly)assembly).GetNativeHandle(), 
-                              searchPath.HasValue, 
-                              (uint) searchPath.GetValueOrDefault(), 
+            return LoadLibraryByName(libraryName, 
+                              assembly,
+                              searchPath,
                               throwOnError: true);
         }
 
@@ -114,13 +113,12 @@ namespace System.Runtime.InteropServices
                 throw new ArgumentNullException(nameof(libraryName));
             if (assembly == null)
                 throw new ArgumentNullException(nameof(assembly));
-            if (!(assembly is RuntimeAssembly))
+            if (!assembly.IsRuntimeImplemented())
                 throw new ArgumentException(SR.Argument_MustBeRuntimeAssembly);
             
-            handle = LoadByName(libraryName, 
-                                ((RuntimeAssembly)assembly).GetNativeHandle(), 
-                                searchPath.HasValue, 
-                                (uint) searchPath.GetValueOrDefault(),
+            handle = LoadLibraryByName(libraryName,
+                                assembly,
+                                searchPath,
                                 throwOnError: false);
             return handle != IntPtr.Zero;
         }
@@ -200,7 +198,7 @@ namespace System.Runtime.InteropServices
                 throw new ArgumentNullException(nameof(assembly));
             if (resolver == null)
                 throw new ArgumentNullException(nameof(resolver));
-            if (!(assembly is RuntimeAssembly))
+            if (!assembly.IsRuntimeImplemented())
                 throw new ArgumentException(SR.Argument_MustBeRuntimeAssembly);
 
             if (s_nativeDllResolveMap == null)
@@ -245,21 +243,5 @@ namespace System.Runtime.InteropServices
 
             return resolver(libraryName, assembly, hasDllImportSearchPathFlags ? (DllImportSearchPath?)dllImportSearchPathFlags : null);
         }
-
-        /// External functions that implement the NativeLibrary interface
-
-        [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
-        internal static extern IntPtr LoadFromPath(string libraryName, bool throwOnError);
-
-        [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
-        internal static extern IntPtr LoadByName(string libraryName, RuntimeAssembly callingAssembly,
-                                                 bool hasDllImportSearchPathFlag, uint dllImportSearchPathFlag, 
-                                                 bool throwOnError);
-
-        [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
-        internal static extern void FreeLib(IntPtr handle);
-
-        [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
-        internal static extern IntPtr GetSymbol(IntPtr handle, string symbolName, bool throwOnError);
     }
 }
diff --git a/src/System.Private.CoreLib/shared/System/Runtime/Loader/LibraryNameVariation.Unix.cs b/src/System.Private.CoreLib/shared/System/Runtime/Loader/LibraryNameVariation.Unix.cs
new file mode 100644 (file)
index 0000000..4895dc8
--- /dev/null
@@ -0,0 +1,69 @@
+// 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.
+
+#nullable enable
+using System.Collections.Generic;
+using System.IO;
+
+namespace System.Runtime.Loader
+{
+    internal partial struct LibraryNameVariation
+    {
+        private const string LibraryNamePrefix = "lib";
+#if PLATFORM_OSX
+        private const string LibraryNameSuffix = ".dylib";
+#else
+        private const string LibraryNameSuffix = ".so";
+#endif
+
+        internal static IEnumerable<LibraryNameVariation> DetermineLibraryNameVariations(string libName, bool isRelativePath)
+        {
+            // This is a copy of the logic in DetermineLibNameVariations in dllimport.cpp in CoreCLR
+
+            if (!isRelativePath)
+            {
+                yield return new LibraryNameVariation(string.Empty, string.Empty);
+            }
+            else
+            {
+                bool containsSuffix = false;
+                int indexOfSuffix = libName.IndexOf(LibraryNameSuffix, StringComparison.OrdinalIgnoreCase);
+                if (indexOfSuffix >= 0)
+                {
+                    indexOfSuffix += LibraryNameSuffix.Length;
+                    containsSuffix = indexOfSuffix == libName.Length || libName[indexOfSuffix] == '.';
+                }
+
+                bool containsDelim = libName.Contains(Path.DirectorySeparatorChar);
+
+                if (containsSuffix)
+                {
+                    yield return new LibraryNameVariation(string.Empty, string.Empty);
+                    if (!containsDelim)
+                    {
+                        yield return new LibraryNameVariation(LibraryNamePrefix, string.Empty);
+                    }
+                    yield return new LibraryNameVariation(string.Empty, LibraryNameSuffix);
+                    if (!containsDelim)
+                    {
+                        yield return new LibraryNameVariation(LibraryNamePrefix, LibraryNameSuffix);
+                    }
+                }
+                else
+                {
+                    yield return new LibraryNameVariation(string.Empty, LibraryNameSuffix);
+                    if (!containsDelim)
+                    {
+                        yield return new LibraryNameVariation(LibraryNamePrefix, LibraryNameSuffix);
+                    }
+                    yield return new LibraryNameVariation(string.Empty, string.Empty);
+                    if (!containsDelim)
+                    {
+                        yield return new LibraryNameVariation(LibraryNamePrefix, string.Empty);
+                    }
+                }
+            }
+        }
+    }
+}
diff --git a/src/System.Private.CoreLib/shared/System/Runtime/Loader/LibraryNameVariation.Windows.cs b/src/System.Private.CoreLib/shared/System/Runtime/Loader/LibraryNameVariation.Windows.cs
new file mode 100644 (file)
index 0000000..99ccb1e
--- /dev/null
@@ -0,0 +1,29 @@
+// 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.
+
+#nullable enable
+using System.Collections.Generic;
+
+namespace System.Runtime.Loader
+{
+    internal partial struct LibraryNameVariation
+    {
+        private const string LibraryNameSuffix = ".dll";
+
+        internal static IEnumerable<LibraryNameVariation> DetermineLibraryNameVariations(string libName, bool isRelativePath)
+        {
+            // This is a copy of the logic in DetermineLibNameVariations in dllimport.cpp in CoreCLR
+
+            yield return new LibraryNameVariation(string.Empty, string.Empty);
+
+            if (isRelativePath &&
+                !libName.EndsWith(".dll", StringComparison.OrdinalIgnoreCase) &&
+                !libName.EndsWith(".exe", StringComparison.OrdinalIgnoreCase))
+            {
+                yield return new LibraryNameVariation(string.Empty, LibraryNameSuffix);
+            }
+        }
+
+    }
+}
diff --git a/src/System.Private.CoreLib/shared/System/Runtime/Loader/LibraryNameVariation.cs b/src/System.Private.CoreLib/shared/System/Runtime/Loader/LibraryNameVariation.cs
new file mode 100644 (file)
index 0000000..029e79a
--- /dev/null
@@ -0,0 +1,20 @@
+// 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.
+
+#nullable enable
+
+namespace System.Runtime.Loader
+{
+    internal partial struct LibraryNameVariation
+    {
+        public string Prefix;
+        public string Suffix;
+
+        public LibraryNameVariation(string prefix, string suffix)
+        {
+            Prefix = prefix;
+            Suffix = suffix;
+        }
+    }
+}
diff --git a/src/System.Private.CoreLib/src/System/Runtime/InteropServices/NativeLibrary.CoreCLR.cs b/src/System.Private.CoreLib/src/System/Runtime/InteropServices/NativeLibrary.CoreCLR.cs
new file mode 100644 (file)
index 0000000..2928f8c
--- /dev/null
@@ -0,0 +1,39 @@
+// 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.
+
+#nullable enable
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Threading;
+
+namespace System.Runtime.InteropServices
+{
+    public static partial class NativeLibrary
+    {
+        internal static IntPtr LoadLibraryByName(string libraryName, Assembly assembly, DllImportSearchPath? searchPath, bool throwOnError)
+        {
+            return LoadByName(libraryName,
+                              ((RuntimeAssembly)assembly).GetNativeHandle(),
+                              searchPath.HasValue,
+                              (uint) searchPath.GetValueOrDefault(),
+                              throwOnError);
+        }
+
+        /// External functions that implement the NativeLibrary interface
+
+        [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
+        internal static extern IntPtr LoadFromPath(string libraryName, bool throwOnError);
+
+        [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
+        internal static extern IntPtr LoadByName(string libraryName, RuntimeAssembly callingAssembly,
+                                                 bool hasDllImportSearchPathFlag, uint dllImportSearchPathFlag, 
+                                                 bool throwOnError);
+
+        [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
+        internal static extern void FreeLib(IntPtr handle);
+
+        [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
+        internal static extern IntPtr GetSymbol(IntPtr handle, string symbolName, bool throwOnError);
+    }
+}
index db20971..4d4c362 100644 (file)
@@ -181,7 +181,7 @@ namespace System.Runtime.Loader
             }
 
             bool isRelativePath = !Path.IsPathFullyQualified(unmanagedDllName);
-            foreach (LibraryNameVariation libraryNameVariation in DetermineLibraryNameVariations(unmanagedDllName, isRelativePath))
+            foreach (LibraryNameVariation libraryNameVariation in LibraryNameVariation.DetermineLibraryNameVariations(unmanagedDllName, isRelativePath))
             {
                 string libraryName = libraryNameVariation.Prefix + unmanagedDllName + libraryNameVariation.Suffix;
                 foreach (string searchPath in searchPaths)
@@ -209,93 +209,10 @@ namespace System.Runtime.Loader
             }
         }
 
-        private struct LibraryNameVariation
-        {
-            public string Prefix;
-            public string Suffix;
-
-            public LibraryNameVariation(string prefix, string suffix)
-            {
-                Prefix = prefix;
-                Suffix = suffix;
-            }
-        }
-
 #if PLATFORM_WINDOWS
         private const CharSet HostpolicyCharSet = CharSet.Unicode;
-        private const string LibraryNameSuffix = ".dll";
-
-        private IEnumerable<LibraryNameVariation> DetermineLibraryNameVariations(string libName, bool isRelativePath)
-        {
-            // This is a copy of the logic in DetermineLibNameVariations in dllimport.cpp in CoreCLR
-
-            yield return new LibraryNameVariation(string.Empty, string.Empty);
-
-            if (isRelativePath &&
-                !libName.EndsWith(".dll", StringComparison.OrdinalIgnoreCase) &&
-                !libName.EndsWith(".exe", StringComparison.OrdinalIgnoreCase))
-            {
-                yield return new LibraryNameVariation(string.Empty, LibraryNameSuffix);
-            }
-        }
 #else
         private const CharSet HostpolicyCharSet = CharSet.Ansi;
-
-        private const string LibraryNamePrefix = "lib";
-#if PLATFORM_OSX
-        private const string LibraryNameSuffix = ".dylib";
-#else
-        private const string LibraryNameSuffix = ".so";
-#endif
-
-        private IEnumerable<LibraryNameVariation> DetermineLibraryNameVariations(string libName, bool isRelativePath)
-        {
-            // This is a copy of the logic in DetermineLibNameVariations in dllimport.cpp in CoreCLR
-
-            if (!isRelativePath)
-            {
-                yield return new LibraryNameVariation(string.Empty, string.Empty);
-            }
-            else
-            {
-                bool containsSuffix = false;
-                int indexOfSuffix = libName.IndexOf(LibraryNameSuffix, StringComparison.OrdinalIgnoreCase);
-                if (indexOfSuffix >= 0)
-                {
-                    indexOfSuffix += LibraryNameSuffix.Length;
-                    containsSuffix = indexOfSuffix == libName.Length || libName[indexOfSuffix] == '.';
-                }
-
-                bool containsDelim = libName.Contains(Path.DirectorySeparatorChar);
-
-                if (containsSuffix)
-                {
-                    yield return new LibraryNameVariation(string.Empty, string.Empty);
-                    if (!containsDelim)
-                    {
-                        yield return new LibraryNameVariation(LibraryNamePrefix, string.Empty);
-                    }
-                    yield return new LibraryNameVariation(string.Empty, LibraryNameSuffix);
-                    if (!containsDelim)
-                    {
-                        yield return new LibraryNameVariation(LibraryNamePrefix, LibraryNameSuffix);
-                    }
-                }
-                else
-                {
-                    yield return new LibraryNameVariation(string.Empty, LibraryNameSuffix);
-                    if (!containsDelim)
-                    {
-                        yield return new LibraryNameVariation(LibraryNamePrefix, LibraryNameSuffix);
-                    }
-                    yield return new LibraryNameVariation(string.Empty, string.Empty);
-                    if (!containsDelim)
-                    {
-                        yield return new LibraryNameVariation(LibraryNamePrefix, string.Empty);
-                    }
-                }
-            }
-        }
 #endif
 
         [UnmanagedFunctionPointer(CallingConvention.Cdecl, CharSet = HostpolicyCharSet)]