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

Added support for libld.so.2 #7

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
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
102 changes: 74 additions & 28 deletions DynamicInterop/UnixLibraryLoader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,15 @@ internal class UnixLibraryLoader : IDynamicLibraryLoader
{
public IntPtr LoadLibrary(string filename)
{
return InternalLoadLibrary(filename);
const int RTLD_LAZY = 0x1;

if (_so == 0)
return InternalLoadLibrary(filename, RTLD_LAZY);

if (_so == 1)
return dlopen1(filename, RTLD_LAZY);
else
return dlopen2(filename, RTLD_LAZY);
}

/// <summary>
Expand All @@ -23,7 +31,13 @@ public IntPtr LoadLibrary(string filename)
/// <returns>The last error.</returns>
public string GetLastError()
{
return dlerror();
if (_so == 0)
throw new Exception("Called GetLastError before LoadLibrary");

if (_so == 1)
return dlerror1();
else
return dlerror2();
}

/// <summary>
Expand All @@ -33,34 +47,48 @@ public string GetLastError()
/// <returns>True if the function dlclose returned 0</returns>
public bool FreeLibrary(IntPtr handle)
{
if (_so == 0)
throw new Exception("Called GetLastError before LoadLibrary");

// according to the manual page on a Debian box
// The function dlclose() returns 0 on success, and nonzero on error.
var status = dlclose(handle);
return status == 0;
if (_so == 1)
{
var status = dlclose1(handle);
return status == 0;
}
else
{
var status = dlclose2(handle);
return status == 0;
}
}

public IntPtr GetFunctionAddress(IntPtr hModule, string lpProcName)
{
return dlsym(hModule, lpProcName);
if (_so == 0)
throw new Exception("Called GetLastError before LoadLibrary");

if (_so == 1)
return dlsym1(hModule, lpProcName);
else
return dlsym2(hModule, lpProcName);
}

internal static IntPtr InternalLoadLibrary(string filename)
internal static IntPtr InternalLoadLibrary(string filename, int lazy)
{
const int RTLD_LAZY = 0x1;
// if (filename.StartsWith ("/")) {
// return dlopen (filename, RTLD_LAZY);
// }
// var searchPaths = getSearchPaths ("LD_LIBRARY_PATH");
// searchPaths.AddRange (getSearchPaths ("PATH"));
// var dll = searchPaths.Select (directory => Path.Combine (directory, filename)).FirstOrDefault (File.Exists);
// if (dll == null) {
// throw new DllNotFoundException ("Could not find the file: " + filename + " on the search path. Checked these directories:\n "
// + String.Join ("\n", searchPaths));
// }

var result = dlopen (filename, RTLD_LAZY);
return result;
try
{
var result = dlopen1(filename, lazy);
_so = 1;
return result;
}
catch (DllNotFoundException)
{
_so = 2;
}

return dlopen2(filename, lazy);
}

static List<string> getSearchPaths(string pathsEnvVar)
Expand All @@ -69,18 +97,36 @@ static List<string> getSearchPaths(string pathsEnvVar)
return searchPaths;
}

[DllImport("libdl")]
private static extern IntPtr dlopen([MarshalAs(UnmanagedType.LPStr)] string filename, int flag);
private static int _so = 0;

[DllImport("libdl.so", EntryPoint = "dlopen")]
private static extern IntPtr dlopen1([MarshalAs(UnmanagedType.LPStr)] string filename, int flag);

[DllImport("libdl")]
[DllImport("libdl.so.2", EntryPoint = "dlopen")]
private static extern IntPtr dlopen2([MarshalAs(UnmanagedType.LPStr)] string filename, int flag);


[DllImport("libdl.so", EntryPoint = "dlerror")]
[return: MarshalAs(UnmanagedType.LPStr)]
private static extern string dlerror1();

[DllImport("libdl.so.2", EntryPoint = "dlerror")]
[return: MarshalAs(UnmanagedType.LPStr)]
private static extern string dlerror();
private static extern string dlerror2();

[DllImport("libdl", EntryPoint = "dlclose")]

[DllImport("libdl.so", EntryPoint = "dlclose")]
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
private static extern int dlclose1(IntPtr hModule);

[DllImport("libdl.so.2", EntryPoint = "dlclose")]
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
private static extern int dlclose(IntPtr hModule);
private static extern int dlclose2(IntPtr hModule);


[DllImport("libdl", EntryPoint = "dlsym")]
private static extern IntPtr dlsym(IntPtr hModule, [MarshalAs(UnmanagedType.LPStr)] string lpProcName);
[DllImport("libdl.so", EntryPoint = "dlsym")]
private static extern IntPtr dlsym1(IntPtr hModule, [MarshalAs(UnmanagedType.LPStr)] string lpProcName);
[DllImport("libdl.so.2", EntryPoint = "dlsym")]
private static extern IntPtr dlsym2(IntPtr hModule, [MarshalAs(UnmanagedType.LPStr)] string lpProcName);
}
}