From 857e529813258139e270b55e914ac1abe8a329d0 Mon Sep 17 00:00:00 2001 From: Sandro Hanea Date: Sat, 28 Dec 2024 13:45:21 +0100 Subject: [PATCH] Fixed libdl.so.2 issue --- .../LibraryLoader/LibdlLibraryLoader.cs | 82 ++++++++++++++++++- 1 file changed, 78 insertions(+), 4 deletions(-) diff --git a/Whisper.net/LibraryLoader/LibdlLibraryLoader.cs b/Whisper.net/LibraryLoader/LibdlLibraryLoader.cs index acddb9c2..7db72c29 100644 --- a/Whisper.net/LibraryLoader/LibdlLibraryLoader.cs +++ b/Whisper.net/LibraryLoader/LibdlLibraryLoader.cs @@ -6,6 +6,10 @@ namespace Whisper.net.LibraryLoader; internal class LibdlLibraryLoader : ILibraryLoader { + // We need to use the libdl.so.2 library on some systems + // We use this flag to remember which one to use, so we don't have to check every time + private bool? useLibdl2; + [DllImport("libdl", CharSet = CharSet.Auto, EntryPoint = "dlopen")] public static extern IntPtr NativeOpenLibraryLibdl(string? filename, int flags); @@ -15,9 +19,39 @@ internal class LibdlLibraryLoader : ILibraryLoader [DllImport("libdl", CharSet = CharSet.Auto, EntryPoint = "dlclose")] public static extern int NativeCloseLibraryLibdl(IntPtr handle); + [DllImport("libdl.so.2", CharSet = CharSet.Auto, EntryPoint = "dlopen")] + public static extern IntPtr NativeOpenLibraryLibdl2(string? filename, int flags); + + [DllImport("libdl.so.2", CharSet = CharSet.Auto, EntryPoint = "dlerror")] + public static extern IntPtr GetLoadError2(); + + [DllImport("libdl.so.2", CharSet = CharSet.Auto, EntryPoint = "dlclose")] + public static extern int NativeCloseLibraryLibdl2(IntPtr handle); + public void CloseLibrary(IntPtr handle) { - NativeCloseLibraryLibdl(handle); + if (useLibdl2.HasValue) + { + if (useLibdl2.Value) + { + NativeCloseLibraryLibdl2(handle); + return; + } + NativeCloseLibraryLibdl(handle); + return; + } + + // We don't know which one can be used, so we try both + try + { + NativeCloseLibraryLibdl(handle); + useLibdl2 = false; + } + catch (DllNotFoundException) + { + NativeCloseLibraryLibdl2(handle); + useLibdl2 = true; + } } public bool TryOpenLibrary(string fileName, out IntPtr libHandle) @@ -25,8 +59,25 @@ public bool TryOpenLibrary(string fileName, out IntPtr libHandle) try { // open with rtld now + global - libHandle = NativeOpenLibraryLibdl(fileName, 0x00102); - return libHandle != IntPtr.Zero; + if (useLibdl2.HasValue) + { + libHandle = useLibdl2.Value ? NativeOpenLibraryLibdl2(fileName, 0x00102) : NativeOpenLibraryLibdl(fileName, 0x00102); + return libHandle != IntPtr.Zero; + } + + // We don't know which one can be used, so we try both + try + { + libHandle = NativeOpenLibraryLibdl(fileName, 0x00102); + useLibdl2 = false; + return libHandle != IntPtr.Zero; + } + catch (DllNotFoundException) + { + libHandle = NativeOpenLibraryLibdl2(fileName, 0x00102); + useLibdl2 = true; + return libHandle != IntPtr.Zero; + } } catch (DllNotFoundException) { @@ -37,7 +88,30 @@ public bool TryOpenLibrary(string fileName, out IntPtr libHandle) public string GetLastError() { - return Marshal.PtrToStringAnsi(GetLoadError()) ?? "Unknown error"; + if (useLibdl2.HasValue) + { + var error = useLibdl2.Value ? GetLoadError2() : GetLoadError(); + return GetError(error); + } + + // We don't know which one can be used, so we try both + try + { + var error = GetLoadError(); + useLibdl2 = false; + return GetError(error); + } + catch (DllNotFoundException) + { + var error = GetLoadError2(); + useLibdl2 = true; + return GetError(error); + } + } + + private string GetError(IntPtr error) + { + return Marshal.PtrToStringAnsi(error) ?? "Unknown error"; } } #endif