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

Use libdl.dylib (not libdl.so) on Mac #191

Closed
wants to merge 3 commits into from
Closed
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
52 changes: 49 additions & 3 deletions source/icu.net/NativeMethods/NativeMethods.cs
Original file line number Diff line number Diff line change
Expand Up @@ -75,10 +75,10 @@ static NativeMethods()

#region Dynamic method loading

#region Native methods for Unix

private const int RTLD_NOW = 2;

#region Native methods for Linux

private const string LIBDL_NAME = "libdl.so";

[DllImport(LIBDL_NAME, SetLastError = true)]
Expand All @@ -102,6 +102,31 @@ private static string dlerror()

#endregion

#region Native methods for Mac

private const string LIBDL_MAC_NAME = "libdl.dylib";

[DllImport(LIBDL_MAC_NAME, EntryPoint = "dlopen", SetLastError = true)]
private static extern IntPtr dlopen_mac(string file, int mode);

[DllImport(LIBDL_MAC_NAME, EntryPoint = "dlclose", SetLastError = true)]
private static extern int dlclose_mac(IntPtr handle);

[DllImport(LIBDL_MAC_NAME, EntryPoint = "dlsym", SetLastError = true)]
private static extern IntPtr dlsym_mac(IntPtr handle, string name);

[DllImport(LIBDL_MAC_NAME, EntryPoint = "dlerror")]
private static extern IntPtr _dlerror_mac();

private static string dlerror_mac()
{
// Don't free the string returned from _dlerror()!
var ptr = _dlerror_mac();
return Marshal.PtrToStringAnsi(ptr);
}

#endregion

#region Native methods for Windows

[DllImport("kernel32.dll", SetLastError = true)]
Expand Down Expand Up @@ -338,9 +363,19 @@ private static IntPtr GetIcuLibHandle(string basename, int icuVersion)

Trace.WriteLineIf(handle == IntPtr.Zero && lastError != 0, $"Unable to load [{libPath}]. Error: {new Win32Exception(lastError).Message}");
}
else if (IsMac)
{
var libName = $"lib{basename}.{icuVersion}.dylib";
libPath = string.IsNullOrEmpty(_IcuPath) ? libName : Path.Combine(_IcuPath, libName);

handle = dlopen_mac(libPath, RTLD_NOW);
lastError = Marshal.GetLastWin32Error();

Trace.WriteLineIf(handle == IntPtr.Zero && lastError != 0, $"Unable to load [{libPath}]. Error: {lastError} ({dlerror_mac()})");
}
else
{
var libName = IsMac ? $"lib{basename}.{icuVersion}.dylib" : $"lib{basename}.so.{icuVersion}";
var libName = $"lib{basename}.so.{icuVersion}";
libPath = string.IsNullOrEmpty(_IcuPath) ? libName : Path.Combine(_IcuPath, libName);

handle = dlopen(libPath, RTLD_NOW);
Expand Down Expand Up @@ -395,6 +430,13 @@ internal static void Cleanup()
if (_IcuI18NLibHandle != IntPtr.Zero)
FreeLibrary(_IcuI18NLibHandle);
}
else if (IsMac)
{
if (_IcuCommonLibHandle != IntPtr.Zero)
dlclose_mac(_IcuCommonLibHandle);
if (_IcuI18NLibHandle != IntPtr.Zero)
dlclose_mac(_IcuI18NLibHandle);
}
else
{
if (_IcuCommonLibHandle != IntPtr.Zero)
Expand Down Expand Up @@ -431,13 +473,17 @@ private static T GetMethod<T>(IntPtr handle, string methodName, bool missingInMi
var versionedMethodName = $"{methodName}_{IcuVersion}";
var methodPointer = IsWindows ?
GetProcAddress(handle, versionedMethodName) :
IsMac ?
dlsym_mac(handle, versionedMethodName):
dlsym(handle, versionedMethodName);

// Some systems (eg. Tizen) don't use methods with IcuVersion suffix
if (methodPointer == IntPtr.Zero)
{
methodPointer = IsWindows ?
GetProcAddress(handle, methodName) :
IsMac ?
dlsym_mac(handle, methodName):
dlsym(handle, methodName);
}
if (methodPointer != IntPtr.Zero)
Expand Down
Loading