Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixed libdl.so.2 issue #314

Merged
merged 1 commit into from
Dec 28, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
82 changes: 78 additions & 4 deletions Whisper.net/LibraryLoader/LibdlLibraryLoader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand All @@ -15,18 +19,65 @@ 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)
{
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)
{
Expand All @@ -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
Loading