protected virtual void Dispose(bool disposing) { if (_handle != IntPtr.Zero && disposing) { _btrCall = null; _btrCallId = null; #if WINDOWS if (_dependencyHandles != null) { foreach (var dependencyHandle in Enumerable.Reverse(_dependencyHandles)) { NativeMethods.FreeLibrary(dependencyHandle); } } NativeMethods.FreeLibrary(_handle); #endif #if LINUX if (_dependencyHandles != null) { foreach (var dependencyHandle in Enumerable.Reverse(_dependencyHandles)) { NativeMethods.dlclose(dependencyHandle); } } NativeMethods.dlclose(_handle); #endif _dependencyHandles = null; _handle = IntPtr.Zero; } }
NativeLibrary(string dllPath = null, IEnumerable <string> dependencyPaths = null) { if (dllPath == null) { dllPath = NativeLibrary.DefaultLibraryPath; } if (dependencyPaths == null) { dependencyPaths = NativeLibrary.DefaultDependencyPaths; } #if WINDOWS if (dependencyPaths != null) { _dependencyHandles = new List <IntPtr>(); foreach (var dependencyPath in dependencyPaths) { var handle = NativeMethods.LoadLibrary(dependencyPath); if (handle != IntPtr.Zero) { _dependencyHandles.Add(handle); } } } _handle = NativeMethods.LoadLibrary(dllPath); if (_handle == IntPtr.Zero) { if (_dependencyHandles != null) { foreach (var dependencyHandle in Enumerable.Reverse(_dependencyHandles)) { NativeMethods.FreeLibrary(dependencyHandle); } } throw new ArgumentException(); } var btrCallFunctionPointer = NativeMethods.GetProcAddress(_handle, "BTRCALL"); var btrCallIdFunctionPointer = NativeMethods.GetProcAddress(_handle, "BTRCALLID"); try { _btrCall = (BtrCallDelegate)Marshal.GetDelegateForFunctionPointer(btrCallFunctionPointer, typeof(BtrCallDelegate)); _btrCallId = (BtrCallIdDelegate)Marshal.GetDelegateForFunctionPointer(btrCallIdFunctionPointer, typeof(BtrCallIdDelegate)); } catch { foreach (var dependencyHandle in _dependencyHandles) { NativeMethods.FreeLibrary(dependencyHandle); } NativeMethods.FreeLibrary(_handle); throw new ArgumentException(); } #endif #if LINUX if (dependencyPaths != null) { _dependencyHandles = new List <IntPtr>(); foreach (var dependencyPath in dependencyPaths) { var handle = NativeMethods.dlopen(dependencyPath, RTLD_NOW | RTLD_GLOBAL); if (handle != IntPtr.Zero) { _dependencyHandles.Add(handle); } } } _handle = NativeMethods.dlopen(dllPath, RTLD_NOW | RTLD_GLOBAL); if (_handle == IntPtr.Zero) { if (_dependencyHandles != null) { foreach (var dependencyHandle in Enumerable.Reverse(_dependencyHandles)) { NativeMethods.dlclose(dependencyHandle); } } throw new ArgumentException(); } var btrCallFunctionPointer = NativeMethods.dlsym(_handle, "BTRCALL"); var btrCallIdFunctionPointer = NativeMethods.dlsym(_handle, "BTRCALLID"); try { _btrCall = (BtrCallDelegate)Marshal.GetDelegateForFunctionPointer(btrCallFunctionPointer, typeof(BtrCallDelegate)); _btrCallId = (BtrCallIdDelegate)Marshal.GetDelegateForFunctionPointer(btrCallIdFunctionPointer, typeof(BtrCallIdDelegate)); } catch { foreach (var dependencyHandle in _dependencyHandles) { NativeMethods.dlclose(dependencyHandle); } NativeMethods.dlclose(_handle); throw new ArgumentException(); } #endif }