return new FunctionLoadResult<T>(FunctionLoadResultKind.LibraryNotFound, null);
}
+#if netcoreapp20
IntPtr funcPtr = LoadFunctionPointer(nativeLibraryHandle, funcName);
if (funcPtr == IntPtr.Zero)
{
{
return new FunctionLoadResult<T>(FunctionLoadResultKind.Success, Marshal.GetDelegateForFunctionPointer<T>(funcPtr));
}
+#else // use managed NativeLibrary API from .NET Core 3 onwards
+ return NativeLibrary.TryGetExport(nativeLibraryHandle, funcName, out var funcPtr)
+ ? new FunctionLoadResult<T>(FunctionLoadResultKind.Success, Marshal.GetDelegateForFunctionPointer<T>(funcPtr))
+ : new FunctionLoadResult<T>(FunctionLoadResultKind.FunctionNotFound, null);
+#endif
});
return new FunctionWrapper<T>(lazyDelegate, libName, funcName);
public static bool IsDrawingSupported { get; } =
RuntimeInformation.IsOSPlatform(OSPlatform.OSX)
-#if netcoreapp30
- ? NativeLibrary.TryLoad("libgdiplus.dylib", out _)
- : NativeLibrary.TryLoad("libgdiplus.so", out _) || NativeLibrary.TryLoad("libgdiplus.so.0", out _);
-#else
+#if netcoreapp20
? dlopen("libgdiplus.dylib", RTLD_LAZY) != IntPtr.Zero
: dlopen("libgdiplus.so", RTLD_LAZY) != IntPtr.Zero || dlopen("libgdiplus.so.0", RTLD_LAZY) != IntPtr.Zero;
- public static bool IsInContainer => RuntimeInformation.IsOSPlatform(OSPlatform.Linux) && File.Exists("/.dockerenv");
-
[DllImport("libdl")]
private static extern IntPtr dlopen(string libName, int flags);
private const int RTLD_LAZY = 0x001;
+#else // use managed NativeLibrary API from .NET Core 3 onwards
+ ? NativeLibrary.TryLoad("libgdiplus.dylib", out _)
+ : NativeLibrary.TryLoad("libgdiplus.so", out _) || NativeLibrary.TryLoad("libgdiplus.so.0", out _);
#endif
+ public static bool IsInContainer => RuntimeInformation.IsOSPlatform(OSPlatform.Linux) && File.Exists("/.dockerenv");
+
public static bool IsSoundPlaySupported { get; } = false;
public static Version OSXVersion { get; } = ToVersion(PlatformApis.GetOSVersion());
<Compile Include="$(CommonPath)\Interop\Unix\Interop.Libraries.cs">
<Link>Common\Interop\Unix\Interop.Libraries.cs</Link>
</Compile>
- <Compile Include="$(CommonPath)\Interop\Unix\libdl\Interop.dlopen.cs">
+ <Compile Include="$(CommonPath)\Interop\Unix\libdl\Interop.dlopen.cs" Condition="'$(TargetGroup)' == 'netcoreapp2.0'">
<Link>Common\Interop\Unix\libdl\Interop.dlopen.cs</Link>
</Compile>
</ItemGroup>
<Compile Include="$(CommonPath)\Interop\Unix\Interop.Libraries.cs">
<Link>Common\Interop\Unix\Interop.Libraries.cs</Link>
</Compile>
+ <EmbeddedResource Include="Resources\System\Drawing\Error.ico">
+ <LogicalName>placeholder.ico</LogicalName>
+ </EmbeddedResource>
+ </ItemGroup>
+ <ItemGroup Condition="'$(TargetGroup)' == 'netcoreapp2.0' AND '$(TargetsUnix)' == 'true'">
<Compile Include="$(CommonPath)\Interop\Unix\libdl\Interop.dlopen.cs">
<Link>Common\Interop\Unix\libdl\Interop.dlopen.cs</Link>
</Compile>
<Compile Include="$(CommonPath)\System\Runtime\InteropServices\FunctionWrapper.Unix.cs">
<Link>Common\System\Runtime\InteropServices\FunctionWrapper.Unix.cs</Link>
</Compile>
- <EmbeddedResource Include="Resources\System\Drawing\Error.ico">
- <LogicalName>placeholder.ico</LogicalName>
- </EmbeddedResource>
</ItemGroup>
<ItemGroup Condition="'$(TargetsNetFx)' != 'true'">
<Reference Include="Microsoft.Win32.Primitives" />
if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
{
libraryName = "libgdiplus.dylib";
+
+#if netcoreapp20
lib = Interop.Libdl.dlopen(libraryName, Interop.Libdl.RTLD_LAZY);
+#else // use managed NativeLibrary API from .NET Core 3 onwards
+ var assembly = System.Reflection.Assembly.GetExecutingAssembly();
+ NativeLibrary.TryLoad(libraryName, assembly, default, out lib);
+#endif
}
else
{
// a global configuration setting. We prefer the "unversioned" shared object name, and fallback to
// the name suffixed with ".0".
libraryName = "libgdiplus.so";
+
+#if netcoreapp20
lib = Interop.Libdl.dlopen(libraryName, Interop.Libdl.RTLD_LAZY);
if (lib == IntPtr.Zero)
{
lib = Interop.Libdl.dlopen("libgdiplus.so.0", Interop.Libdl.RTLD_LAZY);
}
+#else // use managed NativeLibrary API from .NET Core 3 onwards
+ var assembly = System.Reflection.Assembly.GetExecutingAssembly();
+ if (!NativeLibrary.TryLoad(libraryName, assembly, default, out lib))
+ {
+ NativeLibrary.TryLoad("libgdiplus.so.0", assembly, default, out lib);
+ }
+#endif
}
+#if netcoreapp20
// If we couldn't find libgdiplus in the system search path, try to look for libgdiplus in the
// NuGet package folders. This matches the DllImport behavior.
if (lib == IntPtr.Zero)
var searchPath = Path.Combine(searchDirectory, libraryName);
lib = Interop.Libdl.dlopen(searchPath, Interop.Libdl.RTLD_LAZY);
-
if (lib != IntPtr.Zero)
{
break;
}
}
}
+#endif
// This function may return a null handle. If it does, individual functions loaded from it will throw a DllNotFoundException,
// but not until an attempt is made to actually use the function (rather than load it). This matches how PInvokes behave.
return lib;
}
- private static IntPtr LoadFunctionPointer(IntPtr nativeLibraryHandle, string functionName) => Interop.Libdl.dlsym(nativeLibraryHandle, functionName);
-
private static void PlatformInitialize()
{
LoadFunctionPointers();
private static IntPtr LoadLibcups()
{
// We allow both "libcups.so" and "libcups.so.2" to be loaded.
+#if netcoreapp20
IntPtr lib = Interop.Libdl.dlopen("libcups.so", Interop.Libdl.RTLD_LAZY);
if (lib == IntPtr.Zero)
{
lib = Interop.Libdl.dlopen("libcups.so.2", Interop.Libdl.RTLD_LAZY);
}
-
+#else // use managed NativeLibrary API from .NET Core 3 onwards
+ if (!NativeLibrary.TryLoad("libcups.so", out IntPtr lib))
+ {
+ NativeLibrary.TryLoad("libcups.so.2", out lib);
+ }
+#endif
return lib;
}