From 498d12bb0dc6b8a3ab20c232a6086ba2638857ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20C=C3=A1ceres?= Date: Mon, 16 Sep 2024 15:55:21 +0200 Subject: [PATCH] Replace custom library load with net8 NativeLibrary (#4) * replace custom library load with net8 NativeLibrary * Minor typo fix. --------- Co-authored-by: jcant0n --- .../Evergine.Bindings.OpenXR/Commands.cs | 9 +- .../Evergine.Bindings.OpenXR.csproj | 10 +- .../Generated/Commands.cs | 2 +- .../Evergine.Bindings.OpenXR/Kernel32.cs | 19 --- OpenXRGen/Evergine.Bindings.OpenXR/Libdl.cs | 24 ---- .../Evergine.Bindings.OpenXR/NativeLibrary.cs | 101 +++---------- .../OperatingSystemHelper.cs | 133 ------------------ OpenXRGen/OpenXRGen/Program.cs | 2 +- 8 files changed, 35 insertions(+), 265 deletions(-) delete mode 100644 OpenXRGen/Evergine.Bindings.OpenXR/Kernel32.cs delete mode 100644 OpenXRGen/Evergine.Bindings.OpenXR/Libdl.cs delete mode 100644 OpenXRGen/Evergine.Bindings.OpenXR/OperatingSystemHelper.cs diff --git a/OpenXRGen/Evergine.Bindings.OpenXR/Commands.cs b/OpenXRGen/Evergine.Bindings.OpenXR/Commands.cs index 50b3c00..22d2f4c 100644 --- a/OpenXRGen/Evergine.Bindings.OpenXR/Commands.cs +++ b/OpenXRGen/Evergine.Bindings.OpenXR/Commands.cs @@ -1,6 +1,5 @@ using System; using System.Runtime.InteropServices; -using static Evergine.Bindings.OpenXR.OperatingSystemHelper; namespace Evergine.Bindings.OpenXR { @@ -15,7 +14,7 @@ public static unsafe partial class OpenXRNative static OpenXRNative() { nativeLib = LoadNativeLibrary(); - LoadFuncionPointers(); + LoadFunctionPointers(); } private static NativeLibrary LoadNativeLibrary() @@ -25,16 +24,16 @@ private static NativeLibrary LoadNativeLibrary() private static string GetOpenXRName() { - if (IsOSPlatform(PlatformType.Windows)) + if (OperatingSystem.IsWindows()) { return "openxr_loader.dll"; } - else if (IsOSPlatform(PlatformType.Android)) + else if (OperatingSystem.IsAndroid()) { // Android return "libopenxr_loader.so"; } - else if (IsOSPlatform(PlatformType.Linux)) + else if (OperatingSystem.IsLinux()) { // Desktop Linux return "libopenxr_loader.so.1"; diff --git a/OpenXRGen/Evergine.Bindings.OpenXR/Evergine.Bindings.OpenXR.csproj b/OpenXRGen/Evergine.Bindings.OpenXR/Evergine.Bindings.OpenXR.csproj index fbd027e..0e85ef5 100644 --- a/OpenXRGen/Evergine.Bindings.OpenXR/Evergine.Bindings.OpenXR.csproj +++ b/OpenXRGen/Evergine.Bindings.OpenXR/Evergine.Bindings.OpenXR.csproj @@ -2,6 +2,10 @@ net8.0 + Copyright (c) Evergine 2024 + Evergine Team + Plain Concepts + Low-level bindings for OpenXR used in Evergine https://github.com/EvergineTeam/OpenXR.NET icon.png README.md @@ -16,10 +20,8 @@ - - - - + + diff --git a/OpenXRGen/Evergine.Bindings.OpenXR/Generated/Commands.cs b/OpenXRGen/Evergine.Bindings.OpenXR/Generated/Commands.cs index 4d797af..3b79b3e 100644 --- a/OpenXRGen/Evergine.Bindings.OpenXR/Generated/Commands.cs +++ b/OpenXRGen/Evergine.Bindings.OpenXR/Generated/Commands.cs @@ -1715,7 +1715,7 @@ public static XrResult xrPollFutureEXT(XrInstance instance, XrFuturePollInfoEXT* public static XrResult xrCancelFutureEXT(XrInstance instance, XrFutureCancelInfoEXT* cancelInfo) => xrCancelFutureEXT_ptr(instance, cancelInfo); - public static void LoadFuncionPointers(XrInstance instance = default) + public static void LoadFunctionPointers(XrInstance instance = default) { if (instance != default) { diff --git a/OpenXRGen/Evergine.Bindings.OpenXR/Kernel32.cs b/OpenXRGen/Evergine.Bindings.OpenXR/Kernel32.cs deleted file mode 100644 index e4508c7..0000000 --- a/OpenXRGen/Evergine.Bindings.OpenXR/Kernel32.cs +++ /dev/null @@ -1,19 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Runtime.InteropServices; -using System.Text; - -namespace Evergine.Bindings.OpenXR -{ - internal static class Kernel32 - { - [DllImport("kernel32")] - public static extern IntPtr LoadLibrary(string fileName); - - [DllImport("kernel32")] - public static extern IntPtr GetProcAddress(IntPtr module, string procName); - - [DllImport("kernel32")] - public static extern int FreeLibrary(IntPtr module); - } -} diff --git a/OpenXRGen/Evergine.Bindings.OpenXR/Libdl.cs b/OpenXRGen/Evergine.Bindings.OpenXR/Libdl.cs deleted file mode 100644 index 8fe9f9f..0000000 --- a/OpenXRGen/Evergine.Bindings.OpenXR/Libdl.cs +++ /dev/null @@ -1,24 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Runtime.InteropServices; -using System.Text; - -namespace Evergine.Bindings.OpenXR -{ - internal static class Libdl - { - [DllImport("libdl")] - public static extern IntPtr dlopen(string fileName, int flags); - - [DllImport("libdl")] - public static extern IntPtr dlsym(IntPtr handle, string name); - - [DllImport("libdl")] - public static extern int dlclose(IntPtr handle); - - [DllImport("libdl")] - public static extern string dlerror(); - - public const int RTLD_NOW = 0x002; - } -} diff --git a/OpenXRGen/Evergine.Bindings.OpenXR/NativeLibrary.cs b/OpenXRGen/Evergine.Bindings.OpenXR/NativeLibrary.cs index 0238710..7df6dce 100644 --- a/OpenXRGen/Evergine.Bindings.OpenXR/NativeLibrary.cs +++ b/OpenXRGen/Evergine.Bindings.OpenXR/NativeLibrary.cs @@ -1,11 +1,11 @@ using System; using System.Diagnostics; -using System.IO; using System.Runtime.InteropServices; +using SysNativeLibrary = System.Runtime.InteropServices.NativeLibrary; namespace Evergine.Bindings.OpenXR { - public abstract class NativeLibrary : IDisposable + public class NativeLibrary : IDisposable { private readonly string libraryName; private readonly IntPtr libraryHandle; @@ -13,7 +13,7 @@ public abstract class NativeLibrary : IDisposable public IntPtr NativeHandle => libraryHandle; - public NativeLibrary(string libraryName) + protected NativeLibrary(string libraryName) { this.libraryName = libraryName; libraryHandle = LoadLibrary(this.libraryName); @@ -23,13 +23,28 @@ public NativeLibrary(string libraryName) } } - protected abstract IntPtr LoadLibrary(string libraryName); - protected abstract void FreeLibrary(IntPtr libraryHandle); - protected abstract IntPtr LoadFunction(string functionName); + protected IntPtr LoadLibrary(string libraryName) + { + if (SysNativeLibrary.TryLoad(libraryName, typeof(NativeLibrary).Assembly, null, out var lib)) + { + return lib; + } + + Debug.WriteLine($" ===> Error loading native library {libraryName}"); + return IntPtr.Zero; + } + + protected void FreeLibrary(IntPtr libraryHandle) + { + if (libraryHandle != IntPtr.Zero) + { + SysNativeLibrary.Free(libraryHandle); + } + } public unsafe void LoadFunction(string name, out T field) { - IntPtr funcPtr = LoadFunction(name); + SysNativeLibrary.TryGetExport(libraryHandle, name, out IntPtr funcPtr); if (funcPtr == IntPtr.Zero) { OpenXRNative.xrGetInstanceProcAddr(instance, (byte*)Marshal.StringToHGlobalAnsi(name), new IntPtr(&funcPtr)); @@ -53,77 +68,7 @@ public void Dispose() public static NativeLibrary Load(string libraryName) { - if (OperatingSystemHelper.IsOSPlatform(OperatingSystemHelper.PlatformType.Windows)) - { - return new WindowsNativeLibrary(libraryName); - } - else if (OperatingSystemHelper.IsOSPlatform(OperatingSystemHelper.PlatformType.Android) - || OperatingSystemHelper.IsOSPlatform(OperatingSystemHelper.PlatformType.Linux) - || OperatingSystemHelper.IsOSPlatform(OperatingSystemHelper.PlatformType.MacOS)) - { - return new UnixNativeLibrary(libraryName); - } - else - { - throw new PlatformNotSupportedException("Cannot load native libraries on this platform: " + RuntimeInformation.OSDescription); - } - } - - private class WindowsNativeLibrary : NativeLibrary - { - public WindowsNativeLibrary(string libraryName) : base(libraryName) - { - } - - protected override IntPtr LoadLibrary(string libraryName) - { - return Kernel32.LoadLibrary(libraryName); - } - - protected override void FreeLibrary(IntPtr libraryHandle) - { - Kernel32.FreeLibrary(libraryHandle); - } - - protected override IntPtr LoadFunction(string functionName) - { - Debug.WriteLine("Loading " + functionName); - return Kernel32.GetProcAddress(NativeHandle, functionName); - } - } - - private class UnixNativeLibrary : NativeLibrary - { - public UnixNativeLibrary(string libraryName) : base(libraryName) - { - } - - protected override IntPtr LoadLibrary(string libraryName) - { - Libdl.dlerror(); - IntPtr handle = Libdl.dlopen(libraryName, Libdl.RTLD_NOW); - if (handle == IntPtr.Zero && !Path.IsPathRooted(libraryName)) - { - string baseDir = AppContext.BaseDirectory; - if (!string.IsNullOrWhiteSpace(baseDir)) - { - string localPath = Path.Combine(baseDir, libraryName); - handle = Libdl.dlopen(localPath, Libdl.RTLD_NOW); - } - } - - return handle; - } - - protected override void FreeLibrary(IntPtr libraryHandle) - { - Libdl.dlclose(libraryHandle); - } - - protected override IntPtr LoadFunction(string functionName) - { - return Libdl.dlsym(NativeHandle, functionName); - } + return new NativeLibrary(libraryName); } } } diff --git a/OpenXRGen/Evergine.Bindings.OpenXR/OperatingSystemHelper.cs b/OpenXRGen/Evergine.Bindings.OpenXR/OperatingSystemHelper.cs deleted file mode 100644 index 5b2e9bb..0000000 --- a/OpenXRGen/Evergine.Bindings.OpenXR/OperatingSystemHelper.cs +++ /dev/null @@ -1,133 +0,0 @@ -// Copyright © Plain Concepts S.L.U. All rights reserved. Use is subject to license terms. - -using System; -#if !NET5_0_OR_GREATER -using System.Runtime.InteropServices; -#endif - -namespace Evergine.Bindings.OpenXR -{ - internal static class OperatingSystemHelper - { - public static bool IsOSPlatform(PlatformType platform) - { -#if NET5_0_OR_GREATER - switch (platform) - { - case PlatformType.Windows: - return OperatingSystem.IsWindows(); - case PlatformType.Linux: - return OperatingSystem.IsLinux(); - case PlatformType.Android: - return OperatingSystem.IsAndroid(); - case PlatformType.MacOS: - return OperatingSystem.IsMacOS(); - case PlatformType.iOS: - return OperatingSystem.IsIOS(); - default: - return false; - } -#else - OSPlatform osPlatform; - switch (platform) - { - case PlatformType.Windows: - osPlatform = OSPlatform.Windows; - break; - case PlatformType.Linux: - case PlatformType.Android: - osPlatform = OSPlatform.Linux; - break; - case PlatformType.MacOS: - case PlatformType.iOS: - osPlatform = OSPlatform.OSX; - break; - } - - bool matching = RuntimeInformation.IsOSPlatform(osPlatform); - if (matching && platform == PlatformType.Android) - { - matching = RuntimeInformation.OSDescription.Contains("Unix"); - } - else if (matching && platform == PlatformType.iOS) - { - matching = RuntimeInformation.OSDescription.Contains("Darwin"); - } - - return matching; -#endif - } - - public static PlatformType GetCurrentPlatfom() - { - if (IsOSPlatform(PlatformType.Windows)) - { - return PlatformType.Windows; - } - else if (IsOSPlatform(PlatformType.Android)) - { - return PlatformType.Android; - } - else if (IsOSPlatform(PlatformType.Linux)) - { - return PlatformType.Linux; - } - else if (IsOSPlatform(PlatformType.iOS)) - { - return PlatformType.iOS; - } - else if (IsOSPlatform(PlatformType.MacOS)) - { - return PlatformType.MacOS; - } - - return PlatformType.Undefined; - } - - /// - /// Specifies the platform type. - /// - public enum PlatformType - { - /// - /// Undefined platform. - /// - Undefined, - - /// - /// Microsoft Windows platform. - /// - Windows, - - /// - /// Google Android Platform. - /// - Android, - - /// - /// Apple iOS platform. - /// - iOS, - - /// - /// Linux platform. - /// - Linux, - - /// - /// Apple MacOS platform. - /// - MacOS, - - /// - /// Universal Windows App - /// - UWP, - - /// - /// Web platform. - /// - Web, - } - } -} diff --git a/OpenXRGen/OpenXRGen/Program.cs b/OpenXRGen/OpenXRGen/Program.cs index 4ecc586..eec538c 100644 --- a/OpenXRGen/OpenXRGen/Program.cs +++ b/OpenXRGen/OpenXRGen/Program.cs @@ -261,7 +261,7 @@ static void Main(string[] args) file.WriteLine($"\t\t\t=> {command.Prototype.Name}_ptr({command.GetParametersSignature(openXRSpec, useTypes: false)});\n"); } - file.WriteLine($"\t\tpublic static void LoadFuncionPointers(XrInstance instance = default)"); + file.WriteLine($"\t\tpublic static void LoadFunctionPointers(XrInstance instance = default)"); file.WriteLine("\t\t{"); file.WriteLine("\t\t\tif (instance != default)"); file.WriteLine("\t\t\t{");