committed by
GitHub
27 changed files with 270 additions and 321 deletions
@ -0,0 +1,122 @@ |
|||
using System; |
|||
using System.ComponentModel; |
|||
using System.Reflection; |
|||
using System.Runtime.InteropServices; |
|||
using Avalonia.Compatibility; |
|||
using Avalonia.Platform.Interop; |
|||
|
|||
namespace Avalonia.Compatibility |
|||
{ |
|||
internal class NativeLibraryEx |
|||
{ |
|||
#if NET6_0_OR_GREATER
|
|||
public static IntPtr Load(string dll, Assembly assembly) => NativeLibrary.Load(dll, assembly, null); |
|||
public static IntPtr Load(string dll) => NativeLibrary.Load(dll); |
|||
public static bool TryGetExport(IntPtr handle, string name, out IntPtr address) => |
|||
NativeLibrary.TryGetExport(handle, name, out address); |
|||
#else
|
|||
public static IntPtr Load(string dll, Assembly assembly) => Load(dll); |
|||
public static IntPtr Load(string dll) |
|||
{ |
|||
var handle = DlOpen!(dll); |
|||
if (handle != IntPtr.Zero) |
|||
return handle; |
|||
throw new InvalidOperationException("Unable to load " + dll, DlError!()); |
|||
} |
|||
|
|||
public static bool TryGetExport(IntPtr handle, string name, out IntPtr address) |
|||
{ |
|||
try |
|||
{ |
|||
address = DlSym!(handle, name); |
|||
return address != default; |
|||
} |
|||
catch (Exception) |
|||
{ |
|||
address = default; |
|||
return false; |
|||
} |
|||
} |
|||
|
|||
static NativeLibraryEx() |
|||
{ |
|||
if (OperatingSystemEx.IsWindows()) |
|||
{ |
|||
Win32Imports.Init(); |
|||
} |
|||
else if (OperatingSystemEx.IsLinux() || OperatingSystemEx.IsMacOS()) |
|||
{ |
|||
var buffer = Marshal.AllocHGlobal(0x1000); |
|||
uname(buffer); |
|||
var unixName = Marshal.PtrToStringAnsi(buffer); |
|||
Marshal.FreeHGlobal(buffer); |
|||
if (unixName == "Darwin") |
|||
OsXImports.Init(); |
|||
else |
|||
LinuxImports.Init(); |
|||
} |
|||
} |
|||
|
|||
private static Func<string, IntPtr>? DlOpen; |
|||
private static Func<IntPtr, string, IntPtr>? DlSym; |
|||
private static Func<Exception?>? DlError; |
|||
|
|||
[DllImport("libc")] |
|||
static extern int uname(IntPtr buf); |
|||
|
|||
static class Win32Imports |
|||
{ |
|||
[DllImport("kernel32", CharSet = CharSet.Ansi, ExactSpelling = true, SetLastError = true)] |
|||
private static extern IntPtr GetProcAddress(IntPtr hModule, string procName); |
|||
|
|||
[DllImport("kernel32", EntryPoint = "LoadLibraryW", SetLastError = true, CharSet = CharSet.Unicode)] |
|||
private static extern IntPtr LoadLibrary(string lpszLib); |
|||
|
|||
public static void Init() |
|||
{ |
|||
DlOpen = LoadLibrary; |
|||
DlSym = GetProcAddress; |
|||
DlError = () => new Win32Exception(Marshal.GetLastWin32Error()); |
|||
} |
|||
} |
|||
|
|||
static class LinuxImports |
|||
{ |
|||
[DllImport("libdl.so.2")] |
|||
private static extern IntPtr dlopen(string path, int flags); |
|||
|
|||
[DllImport("libdl.so.2")] |
|||
private static extern IntPtr dlsym(IntPtr handle, string symbol); |
|||
|
|||
[DllImport("libdl.so.2")] |
|||
private static extern IntPtr dlerror(); |
|||
|
|||
public static void Init() |
|||
{ |
|||
DlOpen = s => dlopen(s, 1); |
|||
DlSym = dlsym; |
|||
DlError = () => new InvalidOperationException(Marshal.PtrToStringAnsi(dlerror())); |
|||
} |
|||
} |
|||
|
|||
static class OsXImports |
|||
{ |
|||
[DllImport("/usr/lib/libSystem.dylib")] |
|||
private static extern IntPtr dlopen(string path, int flags); |
|||
|
|||
[DllImport("/usr/lib/libSystem.dylib")] |
|||
private static extern IntPtr dlsym(IntPtr handle, string symbol); |
|||
|
|||
[DllImport("/usr/lib/libSystem.dylib")] |
|||
private static extern IntPtr dlerror(); |
|||
|
|||
public static void Init() |
|||
{ |
|||
DlOpen = s => dlopen(s, 1); |
|||
DlSym = dlsym; |
|||
DlError = () => new InvalidOperationException(Marshal.PtrToStringAnsi(dlerror())); |
|||
} |
|||
} |
|||
#endif
|
|||
} |
|||
} |
|||
@ -1,161 +0,0 @@ |
|||
using System; |
|||
using System.Runtime.InteropServices; |
|||
using Avalonia.Platform.Interop; |
|||
|
|||
// ReSharper disable InconsistentNaming
|
|||
namespace Avalonia.Platform.Internal |
|||
{ |
|||
class UnixLoader : IDynamicLibraryLoader |
|||
{ |
|||
static class LinuxImports |
|||
{ |
|||
[DllImport("libdl.so.2")] |
|||
private static extern IntPtr dlopen(string path, int flags); |
|||
|
|||
[DllImport("libdl.so.2")] |
|||
private static extern IntPtr dlsym(IntPtr handle, string symbol); |
|||
|
|||
[DllImport("libdl.so.2")] |
|||
private static extern IntPtr dlerror(); |
|||
|
|||
public static void Init() |
|||
{ |
|||
DlOpen = dlopen; |
|||
DlSym = dlsym; |
|||
DlError = dlerror; |
|||
} |
|||
} |
|||
|
|||
static class OsXImports |
|||
{ |
|||
[DllImport("/usr/lib/libSystem.dylib")] |
|||
private static extern IntPtr dlopen(string path, int flags); |
|||
|
|||
[DllImport("/usr/lib/libSystem.dylib")] |
|||
private static extern IntPtr dlsym(IntPtr handle, string symbol); |
|||
|
|||
[DllImport("/usr/lib/libSystem.dylib")] |
|||
private static extern IntPtr dlerror(); |
|||
|
|||
public static void Init() |
|||
{ |
|||
DlOpen = dlopen; |
|||
DlSym = dlsym; |
|||
DlError = dlerror; |
|||
} |
|||
|
|||
} |
|||
|
|||
|
|||
[DllImport("libc")] |
|||
static extern int uname(IntPtr buf); |
|||
|
|||
static UnixLoader() |
|||
{ |
|||
var buffer = Marshal.AllocHGlobal(0x1000); |
|||
uname(buffer); |
|||
var unixName = Marshal.PtrToStringAnsi(buffer); |
|||
Marshal.FreeHGlobal(buffer); |
|||
if (unixName == "Darwin") |
|||
OsXImports.Init(); |
|||
else |
|||
LinuxImports.Init(); |
|||
} |
|||
|
|||
private static Func<string, int, IntPtr>? DlOpen; |
|||
private static Func<IntPtr, string, IntPtr>? DlSym; |
|||
private static Func<IntPtr>? DlError; |
|||
// ReSharper restore InconsistentNaming
|
|||
|
|||
static string? DlErrorString() => Marshal.PtrToStringAnsi(DlError!.Invoke()); |
|||
|
|||
public IntPtr LoadLibrary(string dll) |
|||
{ |
|||
var handle = DlOpen!.Invoke(dll, 1); |
|||
if (handle == IntPtr.Zero) |
|||
throw new DynamicLibraryLoaderException(DlErrorString()!); |
|||
return handle; |
|||
} |
|||
|
|||
public IntPtr GetProcAddress(IntPtr dll, string proc, bool optional) |
|||
{ |
|||
var ptr = DlSym!.Invoke(dll, proc); |
|||
if (ptr == IntPtr.Zero && !optional) |
|||
throw new DynamicLibraryLoaderException(DlErrorString()!); |
|||
return ptr; |
|||
} |
|||
} |
|||
|
|||
internal class Win32Loader : IDynamicLibraryLoader |
|||
{ |
|||
[DllImport("kernel32", CharSet = CharSet.Ansi, ExactSpelling = true, SetLastError = true)] |
|||
private static extern IntPtr GetProcAddress(IntPtr hModule, string procName); |
|||
|
|||
[DllImport("kernel32", EntryPoint = "LoadLibraryW", SetLastError = true, CharSet = CharSet.Unicode)] |
|||
private static extern IntPtr LoadLibrary(string lpszLib); |
|||
|
|||
IntPtr IDynamicLibraryLoader.LoadLibrary(string dll) |
|||
{ |
|||
var handle = LoadLibrary(dll); |
|||
if (handle != IntPtr.Zero) |
|||
return handle; |
|||
var err = Marshal.GetLastWin32Error(); |
|||
|
|||
throw new DynamicLibraryLoaderException("Error loading " + dll + " error " + err); |
|||
} |
|||
|
|||
IntPtr IDynamicLibraryLoader.GetProcAddress(IntPtr dll, string proc, bool optional) |
|||
{ |
|||
var ptr = GetProcAddress(dll, proc); |
|||
if (ptr == IntPtr.Zero && !optional) |
|||
throw new DynamicLibraryLoaderException("Error " + Marshal.GetLastWin32Error()); |
|||
return ptr; |
|||
} |
|||
} |
|||
|
|||
#if NET6_0_OR_GREATER
|
|||
internal class Net6Loader : IDynamicLibraryLoader |
|||
{ |
|||
public IntPtr LoadLibrary(string dll) |
|||
{ |
|||
try |
|||
{ |
|||
return NativeLibrary.Load(dll); |
|||
} |
|||
catch (Exception ex) |
|||
{ |
|||
throw new DynamicLibraryLoaderException("Error loading " + dll, ex); |
|||
} |
|||
} |
|||
|
|||
public IntPtr GetProcAddress(IntPtr dll, string proc, bool optional) |
|||
{ |
|||
try |
|||
{ |
|||
if (optional) |
|||
{ |
|||
return NativeLibrary.TryGetExport(dll, proc, out var address) ? address : default; |
|||
} |
|||
return NativeLibrary.GetExport(dll, proc); |
|||
} |
|||
catch (Exception ex) |
|||
{ |
|||
throw new DynamicLibraryLoaderException("Error " + dll, ex); |
|||
} |
|||
} |
|||
} |
|||
#endif
|
|||
|
|||
internal class NotSupportedLoader : IDynamicLibraryLoader |
|||
{ |
|||
IntPtr IDynamicLibraryLoader.LoadLibrary(string dll) |
|||
{ |
|||
throw new PlatformNotSupportedException(); |
|||
} |
|||
|
|||
IntPtr IDynamicLibraryLoader.GetProcAddress(IntPtr dll, string proc, bool optional) |
|||
{ |
|||
throw new PlatformNotSupportedException(); |
|||
} |
|||
} |
|||
} |
|||
@ -1,24 +0,0 @@ |
|||
using System; |
|||
using Avalonia.Metadata; |
|||
|
|||
namespace Avalonia.Platform.Interop |
|||
{ |
|||
public interface IDynamicLibraryLoader |
|||
{ |
|||
IntPtr LoadLibrary(string dll); |
|||
IntPtr GetProcAddress(IntPtr dll, string proc, bool optional); |
|||
} |
|||
|
|||
public class DynamicLibraryLoaderException : Exception |
|||
{ |
|||
public DynamicLibraryLoaderException(string message) : base(message) |
|||
{ |
|||
|
|||
} |
|||
|
|||
public DynamicLibraryLoaderException(string message, Exception innerException) : base(message, innerException) |
|||
{ |
|||
|
|||
} |
|||
} |
|||
} |
|||
@ -1,26 +1,20 @@ |
|||
using System; |
|||
using System.Threading; |
|||
using Avalonia.Compatibility; |
|||
using Avalonia.Metadata; |
|||
using Avalonia.Platform.Internal; |
|||
|
|||
namespace Avalonia.Platform |
|||
{ |
|||
[PrivateApi] |
|||
public class StandardRuntimePlatform : IRuntimePlatform |
|||
{ |
|||
public IDisposable StartSystemTimer(TimeSpan interval, Action tick) |
|||
{ |
|||
return new Timer(_ => tick(), null, interval, interval); |
|||
} |
|||
|
|||
public IUnmanagedBlob AllocBlob(int size) => new UnmanagedBlob(size); |
|||
|
|||
private static readonly RuntimePlatformInfo s_info = new() |
|||
{ |
|||
IsDesktop = OperatingSystemEx.IsWindows() || OperatingSystemEx.IsMacOS() || OperatingSystemEx.IsLinux(), |
|||
IsMobile = OperatingSystemEx.IsAndroid() || OperatingSystemEx.IsIOS() |
|||
}; |
|||
|
|||
|
|||
|
|||
public virtual RuntimePlatformInfo GetRuntimeInfo() => s_info; |
|||
} |
|||
} |
|||
|
|||
Loading…
Reference in new issue