private static bool PlatformSpecificFreeLibrary(IntPtr libraryAddr) { if (Platform.IsWindows) { return(Windows.FreeLibrary(libraryAddr)); } if (Platform.IsLinux) { if (Platform.IsMono) { return(Mono.dlclose(libraryAddr) != 0); } if (Platform.IsNetCore) { return(CoreClr.dlclose(libraryAddr) != 0); } return(Linux.dlclose(libraryAddr) != 0); } if (Platform.IsMacOSX) { return(MacOsx.dlclose(libraryAddr) != 0); } throw new InvalidOperationException("Unsupported platform."); }
private static IntPtr LoadSymbol(IntPtr handle, string symbolName, out string errorMsg) { errorMsg = null; if (Platform.IsWindows) { // See http://stackoverflow.com/questions/10473310 for background on this. if (Platform.Is64Bit) { return(Windows.GetProcAddress(handle, symbolName)); } else { IntPtr candidate = Windows.GetProcAddress(handle, symbolName); if (candidate != IntPtr.Zero) { return(candidate); } // Yes, we could potentially predict the size... but it's a lot simpler to just try // all the candidates. Most functions have a suffix of @0, @4 or @8 so we won't be trying // many options - and if it takes a little bit longer to fail if we've really got the wrong // library, that's not a big problem. This is only called once per function in the native library. symbolName = "_" + symbolName + "@"; for (int stackSize = 0; stackSize < 128; stackSize += 4) { candidate = Windows.GetProcAddress(handle, symbolName + stackSize); if (candidate != IntPtr.Zero) { return(candidate); } } // Fail. return(IntPtr.Zero); } } if (Platform.IsLinux) { if (Platform.IsMono) { var monoAddr = Mono.dlsym(handle, symbolName); errorMsg = Marshal.PtrToStringAnsi(Mono.dlerror()); return(monoAddr); } if (Platform.IsNetCore) { var coreAddr = CoreClr.dlsym(handle, symbolName); errorMsg = Marshal.PtrToStringAnsi(CoreClr.dlerror()); return(coreAddr); } var addr = Linux.dlsym(handle, symbolName); errorMsg = Marshal.PtrToStringAnsi(Linux.dlerror()); return(addr); } if (Platform.IsMacOSX) { var addr = MacOsx.dlsym(handle, symbolName); errorMsg = Marshal.PtrToStringAnsi(MacOsx.dlerror()); return(addr); } throw new InvalidOperationException("Unsupported platform."); }