public unsafe string GetCoreFixed() { string variable = Variable; if (variable == null) { throw new ArgumentNullException(nameof(variable)); } Span <char> stack = stackalloc char[128]; ValueStringBuilder buffer = new ValueStringBuilder(stack); int returnValue; while ((returnValue = CoreCLR.GetEnvironmentVariable(variable, buffer.RawChars)) > buffer.Capacity) { buffer.EnsureCapacity(returnValue); } if (returnValue == 0) { return(null); } buffer.Length = returnValue; return(buffer.ToString()); }
/// <summary> /// Loads library in a platform specific way. /// </summary> static IntPtr PlatformSpecificLoadLibrary(string libraryPath) { if (IsWindows) { return(Windows.LoadLibrary(libraryPath)); } if (IsLinux) { if (IsMono) { return(Mono.dlopen(libraryPath, RTLD_GLOBAL + RTLD_LAZY)); } if (IsNetCore) { return(CoreCLR.dlopen(libraryPath, RTLD_GLOBAL + RTLD_LAZY)); } return(Linux.dlopen(libraryPath, RTLD_GLOBAL + RTLD_LAZY)); } if (IsMacOSPlatform) { return(MacOSX.dlopen(libraryPath, RTLD_GLOBAL + RTLD_LAZY)); } throw new InvalidOperationException("Unsupported platform."); }
/// <summary> /// Loads symbol in a platform specific way. /// </summary> /// <param name="symbolName"></param> /// <returns></returns> private IntPtr LoadSymbol(string symbolName) { IntPtr pResult = IntPtr.Zero; if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) /* PlatformApis.IsWindows */ { int ErrCode = 0; string errorMsg = ""; // See http://stackoverflow.com/questions/10473310 for background on this. if (Environment.Is64BitProcess) /* PlatformApis.Is64Bit */ { pResult = Windows.GetProcAddress(this.handle, symbolName); if (pResult == IntPtr.Zero) { ErrCode = Marshal.GetLastWin32Error(); errorMsg = Windows.GetLastErrMsg((uint)ErrCode); Console.WriteLine("Error while loading function: " + symbolName + "\n\t" + errorMsg); } return(pResult); } else { // 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) { pResult = Windows.GetProcAddress(this.handle, symbolName + stackSize); if (pResult != IntPtr.Zero) { return(pResult); } } // Fail. return(IntPtr.Zero); } } if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) { if (InteropRuntimeConfig.IsRunningOnMono) /* PlatformApis.IsMono */ { return(Mono.dlsym(this.handle, symbolName)); } if (RuntimeInformation.FrameworkDescription.StartsWith(".NET Core")) /* PlatformApis.IsNetCore */ { return(CoreCLR.dlsym(this.handle, symbolName)); } return(Linux.dlsym(this.handle, symbolName)); } if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) /* PlatformApis.IsMacOSX */ { return(MacOSX.dlsym(this.handle, symbolName)); } throw new InvalidOperationException("Unsupported platform."); }
private IntPtr LoadSymbol(string symbolName) { if (PlatformApis.IsLinux) { if (PlatformApis.IsNetCore) { return(CoreCLR.dlsym(_handle, symbolName)); } } throw new InvalidOperationException("Unsupported Platform."); }
public void Close() { if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { if (this.handle != IntPtr.Zero) { Windows.FreeLibrary(this.handle); this.handle = IntPtr.Zero; } } else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) { if (InteropRuntimeConfig.IsRunningOnMono) { if (this.handle != IntPtr.Zero) { Mono.dlclose(this.handle); this.handle = IntPtr.Zero; } } else if (RuntimeInformation.FrameworkDescription.StartsWith(".NET Core")) { if (this.handle != IntPtr.Zero) { CoreCLR.dlclose(this.handle); this.handle = IntPtr.Zero; } } else { if (this.handle != IntPtr.Zero) { Linux.dlclose(this.handle); this.handle = IntPtr.Zero; } } } else if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) { if (this.handle != IntPtr.Zero) { MacOSX.dlclose(this.handle); this.handle = IntPtr.Zero; } } else { throw new InvalidOperationException("Unsupported platform."); } bLibOpen = false; }
/// <summary> /// Loads symbol in a platform specific way. /// </summary> /// <param name="symbolName"></param> /// <returns></returns> private IntPtr LoadSymbol(string symbolName) { if (PlatformApis.IsWindows) { // See http://stackoverflow.com/questions/10473310 for background on this. //if (PlatformApis.Is64Bit) //{ // return Windows.GetProcAddress(this.handle, symbolName); //} //else //{ // // 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) // { // IntPtr candidate = Windows.GetProcAddress(this.handle, symbolName + stackSize); // if (candidate != IntPtr.Zero) // { // return candidate; // } // } // // Fail. // return IntPtr.Zero; //} // VLFD.dll 比较特殊 // 虽然是32位的,但符号和64位相同 return(Windows.GetProcAddress(this.handle, symbolName)); } if (PlatformApis.IsLinux) { if (PlatformApis.IsMono) { return(Mono.dlsym(this.handle, symbolName)); } if (PlatformApis.IsNetCore) { return(CoreCLR.dlsym(this.handle, symbolName)); } return(Linux.dlsym(this.handle, symbolName)); } if (PlatformApis.IsMacOSX) { return(MacOSX.dlsym(this.handle, symbolName)); } throw new InvalidOperationException("Unsupported platform."); }
/// <summary> /// Loads symbol in a platform specific way. /// </summary> /// <param name="symbolName"></param> /// <returns></returns> public IntPtr LoadSymbol(string symbolName) { if (IsWindows) { // See http://stackoverflow.com/questions/10473310 for background on this. if (Is64Bit) { return(Windows.GetProcAddress(NativeLibraryHandle, symbolName)); } // 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 (var stackSize = 0; stackSize < 128; stackSize += 4) { var candidate = Windows.GetProcAddress(NativeLibraryHandle, symbolName + stackSize); if (candidate != IntPtr.Zero) { return(candidate); } } // Fail. return(IntPtr.Zero); } if (IsLinux) { if (IsMono) { return(Mono.dlsym(NativeLibraryHandle, symbolName)); } if (IsNetCore) { return(CoreCLR.dlsym(NativeLibraryHandle, symbolName)); } return(Linux.dlsym(NativeLibraryHandle, symbolName)); } if (IsMacOSPlatform) { return(MacOSX.dlsym(NativeLibraryHandle, symbolName)); } throw new InvalidOperationException("Unsupported platform."); }
public string GetCore() { string variable = Variable; if (variable == null) { throw new ArgumentNullException(nameof(variable)); } Span <char> buffer = stackalloc char[128]; // a somewhat reasonable default size int requiredSize = CoreCLR.GetEnvironmentVariable(variable, buffer); if (requiredSize == 0 && Marshal.GetLastWin32Error() == ERROR_ENVVAR_NOT_FOUND) { return(null); } if (requiredSize <= buffer.Length) { return(new string(buffer.Slice(0, requiredSize))); } char[] chars = ArrayPool <char> .Shared.Rent(requiredSize); try { buffer = chars; requiredSize = CoreCLR.GetEnvironmentVariable(variable, buffer); if ((requiredSize == 0 && Marshal.GetLastWin32Error() == ERROR_ENVVAR_NOT_FOUND) || requiredSize > buffer.Length) { return(null); } return(new string(buffer.Slice(0, requiredSize))); } finally { ArrayPool <char> .Shared.Return(chars); } }
public unsafe string GetCoreFixedInline() { string variable = Variable; if (variable == null) { throw new ArgumentNullException(nameof(variable)); } Span <char> stack = stackalloc char[128]; ValueStringBuilder buffer = new ValueStringBuilder(stack); int returnValue; while (true) { fixed(char *b = buffer) { if ((returnValue = CoreCLR.GetEnvironmentVariable(variable, b, buffer.Capacity)) <= buffer.Capacity) { break; } else { buffer.EnsureCapacity(returnValue); } } } ; if (returnValue == 0) { return(null); } buffer.Length = returnValue; return(buffer.ToString()); }
static NativeLibrary() { const int RTLD_NOW = 2; if (Platform.IsWindows) { Open = Windows.LoadLibrary; GetSymbol = Windows.GetProcAddress; } else if (Platform.IsOSX) { Open = f => OSX.dlopen(f, RTLD_NOW); GetSymbol = OSX.dlsym; } else if (Platform.IsLinux) { if (Platform.IsMono) { Open = f => Mono.dlopen(f, RTLD_NOW); GetSymbol = Mono.dlsym; } else if (Platform.IsNetCore) { Open = f => CoreCLR.dlopen(f, RTLD_NOW); GetSymbol = CoreCLR.dlsym; } else { Open = f => Linux.dlopen(f, RTLD_NOW); GetSymbol = Linux.dlsym; } } else { throw new PlatformNotSupportedException(); } }