Browse Source

Replace UnixLoader with NativeLibraryEx (#13217)

pull/13260/head
Max Katz 3 years ago
committed by GitHub
parent
commit
b3ff3ab808
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 14
      src/Avalonia.Native/AvaloniaNativePlatform.cs
  2. 125
      src/Avalonia.Native/DynLoader.cs

14
src/Avalonia.Native/AvaloniaNativePlatform.cs

@ -1,5 +1,6 @@
using System;
using System.Runtime.InteropServices;
using Avalonia.Compatibility;
using Avalonia.Controls.Platform;
using Avalonia.Input;
using Avalonia.Input.Platform;
@ -39,15 +40,14 @@ namespace Avalonia.Native
{
if (options.AvaloniaNativeLibraryPath != null)
{
var loader = RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ?
(IDynLoader)new Win32Loader() :
new UnixLoader();
var lib = loader.LoadLibrary(options.AvaloniaNativeLibraryPath);
var proc = loader.GetProcAddress(lib, "CreateAvaloniaNative", false);
var lib = NativeLibraryEx.Load(options.AvaloniaNativeLibraryPath);
if (!NativeLibraryEx.TryGetExport(lib, "CreateAvaloniaNative", out var proc))
{
throw new InvalidOperationException(
"Unable to get \"CreateAvaloniaNative\" export from AvaloniaNativeLibrary library");
}
var d = Marshal.GetDelegateForFunctionPointer<CreateAvaloniaNativeDelegate>(proc);
return Initialize(d(), options);
}
else

125
src/Avalonia.Native/DynLoader.cs

@ -1,125 +0,0 @@
using System;
using System.Runtime.InteropServices;
/*
* Source code imported from https://github.com/kekekeks/evhttp-sharp
* Source is provided under MIT license for Avalonia project and derived works
*/
namespace Avalonia.Native
{
internal interface IDynLoader
{
IntPtr LoadLibrary(string dll);
IntPtr GetProcAddress(IntPtr dll, string proc, bool optional);
}
class UnixLoader : IDynLoader
{
// ReSharper disable InconsistentNaming
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());
public IntPtr LoadLibrary(string dll)
{
var handle = DlOpen(dll, 1);
if (handle == IntPtr.Zero)
throw new Exception(DlErrorString());
return handle;
}
public IntPtr GetProcAddress(IntPtr dll, string proc, bool optional)
{
var ptr = DlSym(dll, proc);
if (ptr == IntPtr.Zero && !optional)
throw new Exception(DlErrorString());
return ptr;
}
}
internal class Win32Loader : IDynLoader
{
[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 IDynLoader.LoadLibrary(string dll)
{
var handle = LoadLibrary(dll);
if (handle != IntPtr.Zero)
return handle;
var err = Marshal.GetLastWin32Error();
throw new Exception("Error loading " + dll + " error " + err);
}
IntPtr IDynLoader.GetProcAddress(IntPtr dll, string proc, bool optional)
{
var ptr = GetProcAddress(dll, proc);
if (ptr == IntPtr.Zero && !optional)
throw new Exception("Error " + Marshal.GetLastWin32Error());
return ptr;
}
}
}
Loading…
Cancel
Save