internal UnmanagedLibrary(string libraryName, SafeLibraryHandle libraryHandle) { if (string.IsNullOrWhiteSpace(libraryName)) { throw new ArgumentException("A valid library name is expected.", nameof(libraryName)); } if (libraryHandle.IsNullOrInvalid()) { throw new ArgumentNullException(nameof(libraryHandle)); } TraceLabel = string.Format("UnmanagedLibrary[{0}]", libraryName); _handle = libraryHandle; }
public static UnmanagedLibrary LoadUnmanagedLibrary(string libraryName) { if (string.IsNullOrWhiteSpace(libraryName)) { throw new ArgumentException("A valid library name is expected.", "libraryName"); } // Now look: This method should ExpandPaths on LibraryPaths. // That being said, it should just enumerate // Path, AppBase, Arch, Compiler, LibraryName, Extension // Secondly, this method should try each /lib/x86_64-linux-gnu/libload.so.2 to load, // Third, this method should try EmbeddedResources, // Finally, this method fails, telling the user all libraryPaths searched. var libraryPaths = new List <string>(Platform.LibraryPaths); Platform.ExpandPaths(libraryPaths, "{System32}", Environment.SystemDirectory); Platform.ExpandPaths(libraryPaths, "{AppBase}", EnsureNotEndingBackSlash( AppDomain.CurrentDomain.BaseDirectory)); Platform.ExpandPaths(libraryPaths, "{LibraryName}", libraryName); // Platform.ExpandPaths(libraryPaths, "{Ext}", Platform.LibraryFileExtension); string architecture; string[] architecturePaths = null; if (Platform.Architecture == ImageFileMachine.I386 && Environment.Is64BitProcess) { architecture = "amd64"; } else { architecture = Enum.GetName(typeof(ImageFileMachine), Platform.Architecture).ToLower(); } if (architecture == "i386") { architecturePaths = new string[] { "i386", "x86" } } ; if (architecture == "amd64") { architecturePaths = new string[] { "amd64", "x64" } } ; if (architecturePaths == null) { architecturePaths = new string[] { architecture } } ; Platform.ExpandPaths(libraryPaths, "{Arch}", architecturePaths); // Expand Compiler Platform.ExpandPaths(libraryPaths, "{Compiler}", Platform.Compiler); // Now TRY the enumerated Directories for libFile.so.* string traceLabel = string.Format("UnmanagedLibrary[{0}]", libraryName); foreach (string libraryPath in libraryPaths) { string folder = null; string filesPattern = libraryPath; int filesPatternI; if (-1 < (filesPatternI = filesPattern.LastIndexOf('\\'))) { folder = filesPattern.Substring(0, filesPatternI + 1); filesPattern = filesPattern.Substring(filesPatternI + 1); } if (string.IsNullOrEmpty(folder) || !Directory.Exists(folder)) { continue; } string[] files = Directory.EnumerateFiles(folder, filesPattern, SearchOption.TopDirectoryOnly).ToArray(); foreach (string file in files) { // Finally, I am really loading this file SafeLibraryHandle handle = OpenHandle(file); if (!handle.IsNullOrInvalid()) { Trace.TraceInformation(string.Format("{0} Loaded binary \"{1}\"", traceLabel, file)); return(new UnmanagedLibrary(libraryName, handle)); } else { Exception nativeEx = GetLastLibraryError(); Trace.TraceInformation(string.Format("{0} Custom binary \"{1}\" not loaded: {2}", traceLabel, file, nativeEx.Message)); } } } // Search ManifestResources for fileName.arch.ext // TODO: Enumerate ManifestResources for ZeroMQ{Arch}{Compiler}{LibraryName}{Ext}.dll string resourceName = string.Format("ZeroMQ.{0}.{1}{2}", libraryName, architecture, ".dll"); string tempPath = Path.Combine(Path.GetTempPath(), resourceName); if (ExtractManifestResource(resourceName, tempPath)) { SafeLibraryHandle handle = OpenHandle(tempPath); if (!handle.IsNullOrInvalid()) { Trace.TraceInformation(string.Format("{0} Loaded binary from EmbeddedResource \"{1}\" from \"{2}\".", traceLabel, resourceName, tempPath)); return(new UnmanagedLibrary(libraryName, handle)); } else { Trace.TraceWarning(string.Format("{0} Unable to run the extracted EmbeddedResource \"{1}\" from \"{2}\".", traceLabel, resourceName, tempPath)); } } else { Trace.TraceWarning(string.Format("{0} Unable to extract the EmbeddedResource \"{1}\" to \"{2}\".", traceLabel, resourceName, tempPath)); } var fnf404 = new StringBuilder(); fnf404.Append(traceLabel); fnf404.Append(" Unable to load binary \""); fnf404.Append(libraryName); fnf404.AppendLine("\" from folders"); foreach (string path in libraryPaths) { fnf404.Append("\t"); fnf404.AppendLine(path); } fnf404.Append(" Also unable to load binary from EmbeddedResource \""); fnf404.Append(resourceName); fnf404.Append("\", from temporary path \""); fnf404.Append(tempPath); fnf404.Append("\". See Trace output for more information."); throw new FileNotFoundException(fnf404.ToString()); }
private static extern IntPtr GetProcAddress(SafeLibraryHandle moduleHandle, string procname);
public static IntPtr LoadProcedure(SafeLibraryHandle handle, string functionName) { return(GetProcAddress(handle, functionName)); }
public static bool IsNullOrInvalid(this SafeLibraryHandle handle) { return(handle == null || handle.IsInvalid); }
private static extern IntPtr dlsym(SafeLibraryHandle handle, IntPtr symbol);
public static IntPtr LoadProcedure(SafeLibraryHandle libHandle, string functionName) { throw new NotSupportedException(); }
public static UnmanagedLibrary LoadUnmanagedLibrary(string libraryName) { if (string.IsNullOrWhiteSpace(libraryName)) { throw new ArgumentException("A valid library name is expected.", "libraryName"); } // Now look: This method should ExpandPaths on LibraryPaths. // That being said, it should just enumerate // Path, AppBase, Arch, Compiler, LibraryName, Extension // Secondly, this method should try each /lib/x86_64-linux-gnu/libload.so.2 to load, // Third, this method should try EmbeddedResources, // Finally, this method fails, telling the user all libraryPaths searched. var libraryPaths = new List <string>(Platform.LibraryPaths); Platform.ExpandPaths(libraryPaths, "{Path}", EnumerateLibLdConf("/etc/ld.so.conf")); var PATHs = new List <string>(); PATHs.Add(EnsureNotEndingSlash(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location))); PATHs.AddRange(EnumerateLibLdPATH()); Platform.ExpandPaths(libraryPaths, "{DllPath}", PATHs); Platform.ExpandPaths(libraryPaths, "{AppBase}", EnsureNotEndingSlash( AppDomain.CurrentDomain.BaseDirectory)); Platform.ExpandPaths(libraryPaths, "{LibraryName}", libraryName); // Platform.ExpandPaths(libraryPaths, "{Ext}", Platform.LibraryFileExtension); string architecture; string[] architecturePaths = null; if (Platform.Architecture == ImageFileMachine.I386 && Environment.Is64BitProcess) { architecture = "amd64"; } else { architecture = Enum.GetName(typeof(ImageFileMachine), Platform.Architecture).ToLower(); } if (architecture == "i386") { architecturePaths = new string[] { "i386", "x86" } } ; if (architecture == "amd64") { architecturePaths = new string[] { "amd64", "x64" } } ; if (architecturePaths == null) { architecturePaths = new string[] { architecture } } ; Platform.ExpandPaths(libraryPaths, "{Arch}", architecturePaths); // Now TRY the enumerated Directories for libFile.so.* string traceLabel = string.Format("UnmanagedLibrary[{0}]", libraryName); foreach (string libraryPath in libraryPaths) { string folder = null; string filesPattern = libraryPath; int filesPatternI; if (-1 < (filesPatternI = filesPattern.LastIndexOf('/'))) { folder = filesPattern.Substring(0, filesPatternI + 1); filesPattern = filesPattern.Substring(filesPatternI + 1); } if (string.IsNullOrEmpty(folder) || !Directory.Exists(folder)) { continue; } string[] files = Directory.EnumerateFiles(folder, filesPattern, SearchOption.TopDirectoryOnly).ToArray(); foreach (string file in files) { // Finally, I am really loading this file SafeLibraryHandle handle = OpenHandle(file); if (!handle.IsNullOrInvalid()) { if (Platform.IsMono) { // This is Platform.Posix. In mono, just dlopen'ing the library doesn't work. // Using DllImport("__Internal", EntryPoint = "mono_dllmap_insert") to get mono on the path. MonoDllMapInsert(libraryName, file); } Trace.TraceInformation(string.Format("{0} Loaded binary \"{1}\"", traceLabel, file)); return(new UnmanagedLibrary(libraryName, handle)); } handle.Close(); Exception nativeEx = GetLastLibraryError(); Trace.TraceInformation(string.Format("{0} Custom binary \"{1}\" not loaded: {2}", traceLabel, file, nativeEx.Message)); } } // Search ManifestResources for fileName.arch.ext string resourceName = string.Format("ZeroMQ.{0}.{1}{2}", libraryName, architecture, ".so"); string tempPath = Path.Combine(Path.GetTempPath(), resourceName); if (ExtractManifestResource(resourceName, tempPath)) { // TODO: need syscall_chmod_execute(path); ? SafeLibraryHandle handle = OpenHandle(tempPath); if (!handle.IsNullOrInvalid()) { if (Platform.IsMono) { MonoDllMapInsert(libraryName, tempPath); } Trace.TraceInformation(string.Format("{0} Loaded binary from EmbeddedResource \"{1}\" from \"{2}\".", traceLabel, resourceName, tempPath)); return(new UnmanagedLibrary(libraryName, handle)); } handle.Close(); Trace.TraceWarning(string.Format("{0} Unable to run the extracted EmbeddedResource \"{1}\" from \"{2}\".", traceLabel, resourceName, tempPath)); } else { Trace.TraceWarning(string.Format("{0} Unable to extract the EmbeddedResource \"{1}\" to \"{2}\".", traceLabel, resourceName, tempPath)); } var fnf404 = new StringBuilder(); fnf404.Append(traceLabel); fnf404.Append(" Unable to load binary \""); fnf404.Append(libraryName); fnf404.AppendLine("\" from folders"); foreach (string path in libraryPaths) { fnf404.Append("\t"); fnf404.AppendLine(path); } fnf404.Append(" Also unable to load binary from EmbeddedResource \""); fnf404.Append(resourceName); fnf404.Append("\", from temporary path \""); fnf404.Append(tempPath); fnf404.Append("\". See Trace output for more information."); throw new FileNotFoundException(fnf404.ToString()); }