// Extracts and loads a resource with the base name into the same directory with the base output name public static void LoadUnmanagedLibrary(string resourceBaseName, string outFile) { if (s_loadedLibs.ContainsKey(resourceBaseName)) { return; } string resName = GetResourceName(resourceBaseName); if (!s_resourceList.Contains(resName)) { throw new Exception($"The native library {resourceBaseName} does not exist as an embedded resource."); } Stopwatch timer = Stopwatch.StartNew(); string outPath = Path.Combine(s_thisDir, outFile); try { WriteResourceStream(resName, outPath); } catch (Exception) { throw; } IntPtr handle = IntPtr.Zero; if (s_platform == PlatformOS.Windows) { handle = Kernel32.LoadLibrary(outPath); if (handle == IntPtr.Zero) { int err = Marshal.GetLastWin32Error(); string errstr = (new Win32Exception(err)).Message; throw new Exception(errstr); } } else { handle = Dl.Open(outPath, Dl.RTLD_NOW); if (handle == IntPtr.Zero) { IntPtr err = Dl.Error(); string errstr = Marshal.PtrToStringAuto(err); throw new Exception(errstr); } } if (s_loadedLibs.Count == 0) { // Unloads the libraries in the event of a crash (or the user forgets) AppDomain.CurrentDomain.ProcessExit += (sender, e) => UnloadLibraries(); } s_loadedLibs.Add(resourceBaseName, handle); s_libPaths.Add(resourceBaseName, outPath); LastLoadTime = timer.Elapsed; }
// Extract the resource into the path and load it private static void ExtractAndLoad(string name) { var rName = GetResourceName(name); var rPath = Path.Combine(s_thisDir, $"{name}.nl"); // Extract using (var reader = s_this.GetManifestResourceStream(rName)) { using (var writer = File.Open(rPath, FileMode.Create, FileAccess.Write, FileShare.None)) { reader.CopyTo(writer); } } s_libPaths.Add(rPath); // Load var handle = (s_platform == PlatformOS.Windows) ? Kernel32.LoadLibrary(rPath) : Dl.Open(rPath, Dl.RTLD_NOW); s_loadedLibs.Add(name, handle); }