|
|
|
@ -51,11 +51,12 @@ namespace Grpc.Core.Internal |
|
|
|
|
|
|
|
|
|
Logger.Debug("Attempting to load native library \"{0}\"", this.libraryPath); |
|
|
|
|
|
|
|
|
|
this.handle = PlatformSpecificLoadLibrary(this.libraryPath); |
|
|
|
|
this.handle = PlatformSpecificLoadLibrary(this.libraryPath, out string loadLibraryErrorDetail); |
|
|
|
|
|
|
|
|
|
if (this.handle == IntPtr.Zero) |
|
|
|
|
{ |
|
|
|
|
throw new IOException(string.Format("Error loading native library \"{0}\"", this.libraryPath)); |
|
|
|
|
throw new IOException(string.Format("Error loading native library \"{0}\". {1}", |
|
|
|
|
this.libraryPath, loadLibraryErrorDetail)); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -129,31 +130,44 @@ namespace Grpc.Core.Internal |
|
|
|
|
/// <summary> |
|
|
|
|
/// Loads library in a platform specific way. |
|
|
|
|
/// </summary> |
|
|
|
|
private static IntPtr PlatformSpecificLoadLibrary(string libraryPath) |
|
|
|
|
private static IntPtr PlatformSpecificLoadLibrary(string libraryPath, out string errorMsg) |
|
|
|
|
{ |
|
|
|
|
if (PlatformApis.IsWindows) |
|
|
|
|
{ |
|
|
|
|
// TODO(jtattermusch): populate the error on Windows |
|
|
|
|
errorMsg = null; |
|
|
|
|
return Windows.LoadLibrary(libraryPath); |
|
|
|
|
} |
|
|
|
|
if (PlatformApis.IsLinux) |
|
|
|
|
{ |
|
|
|
|
if (PlatformApis.IsMono) |
|
|
|
|
{ |
|
|
|
|
return Mono.dlopen(libraryPath, RTLD_GLOBAL + RTLD_LAZY); |
|
|
|
|
return LoadLibraryPosix(Mono.dlopen, Mono.dlerror, libraryPath, out errorMsg); |
|
|
|
|
} |
|
|
|
|
if (PlatformApis.IsNetCore) |
|
|
|
|
{ |
|
|
|
|
return CoreCLR.dlopen(libraryPath, RTLD_GLOBAL + RTLD_LAZY); |
|
|
|
|
return LoadLibraryPosix(CoreCLR.dlopen, CoreCLR.dlerror, libraryPath, out errorMsg); |
|
|
|
|
} |
|
|
|
|
return Linux.dlopen(libraryPath, RTLD_GLOBAL + RTLD_LAZY); |
|
|
|
|
return LoadLibraryPosix(Linux.dlopen, Linux.dlerror, libraryPath, out errorMsg); |
|
|
|
|
} |
|
|
|
|
if (PlatformApis.IsMacOSX) |
|
|
|
|
{ |
|
|
|
|
return MacOSX.dlopen(libraryPath, RTLD_GLOBAL + RTLD_LAZY); |
|
|
|
|
return LoadLibraryPosix(MacOSX.dlopen, MacOSX.dlerror, libraryPath, out errorMsg); |
|
|
|
|
} |
|
|
|
|
throw new InvalidOperationException("Unsupported platform."); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private static IntPtr LoadLibraryPosix(Func<string, int, IntPtr> dlopenFunc, Func<IntPtr> dlerrorFunc, string libraryPath, out string errorMsg) |
|
|
|
|
{ |
|
|
|
|
errorMsg = null; |
|
|
|
|
IntPtr ret = dlopenFunc(libraryPath, RTLD_GLOBAL + RTLD_LAZY); |
|
|
|
|
if (ret == IntPtr.Zero) |
|
|
|
|
{ |
|
|
|
|
errorMsg = Marshal.PtrToStringAnsi(dlerrorFunc()); |
|
|
|
|
} |
|
|
|
|
return ret; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private static string FirstValidLibraryPath(string[] libraryPathAlternatives) |
|
|
|
|
{ |
|
|
|
|
GrpcPreconditions.CheckArgument(libraryPathAlternatives.Length > 0, "libraryPathAlternatives cannot be empty."); |
|
|
|
@ -183,6 +197,9 @@ namespace Grpc.Core.Internal |
|
|
|
|
[DllImport("libdl.so")] |
|
|
|
|
internal static extern IntPtr dlopen(string filename, int flags); |
|
|
|
|
|
|
|
|
|
[DllImport("libdl.so")] |
|
|
|
|
internal static extern IntPtr dlerror(); |
|
|
|
|
|
|
|
|
|
[DllImport("libdl.so")] |
|
|
|
|
internal static extern IntPtr dlsym(IntPtr handle, string symbol); |
|
|
|
|
} |
|
|
|
@ -192,6 +209,9 @@ namespace Grpc.Core.Internal |
|
|
|
|
[DllImport("libSystem.dylib")] |
|
|
|
|
internal static extern IntPtr dlopen(string filename, int flags); |
|
|
|
|
|
|
|
|
|
[DllImport("libSystem.dylib")] |
|
|
|
|
internal static extern IntPtr dlerror(); |
|
|
|
|
|
|
|
|
|
[DllImport("libSystem.dylib")] |
|
|
|
|
internal static extern IntPtr dlsym(IntPtr handle, string symbol); |
|
|
|
|
} |
|
|
|
@ -208,6 +228,9 @@ namespace Grpc.Core.Internal |
|
|
|
|
[DllImport("__Internal")] |
|
|
|
|
internal static extern IntPtr dlopen(string filename, int flags); |
|
|
|
|
|
|
|
|
|
[DllImport("__Internal")] |
|
|
|
|
internal static extern IntPtr dlerror(); |
|
|
|
|
|
|
|
|
|
[DllImport("__Internal")] |
|
|
|
|
internal static extern IntPtr dlsym(IntPtr handle, string symbol); |
|
|
|
|
} |
|
|
|
@ -222,6 +245,9 @@ namespace Grpc.Core.Internal |
|
|
|
|
[DllImport("libcoreclr.so")] |
|
|
|
|
internal static extern IntPtr dlopen(string filename, int flags); |
|
|
|
|
|
|
|
|
|
[DllImport("libcoreclr.so")] |
|
|
|
|
internal static extern IntPtr dlerror(); |
|
|
|
|
|
|
|
|
|
[DllImport("libcoreclr.so")] |
|
|
|
|
internal static extern IntPtr dlsym(IntPtr handle, string symbol); |
|
|
|
|
} |
|
|
|
|