/// <summary> /// Set a callback for resolving native library imports from an assembly. /// This per-assembly resolver is the first attempt to resolve native library loads /// initiated by this assembly. /// /// Only one resolver can be registered per assembly. /// Trying to register a second resolver fails with InvalidOperationException. /// </summary> /// <param name="assembly">The assembly for which the resolver is registered</param> /// <param name="resolver">The resolver callback to register</param> /// <exception cref="System.ArgumentNullException">If assembly or resolver is null</exception> /// <exception cref="System.ArgumentException">If a resolver is already set for this assembly</exception> public static void SetDllImportResolver(Assembly assembly, DllImportResolver resolver) { if (assembly == null) { throw new ArgumentNullException(nameof(assembly)); } if (resolver == null) { throw new ArgumentNullException(nameof(resolver)); } if (!assembly.IsRuntimeImplemented()) { throw new ArgumentException(SR.Argument_MustBeRuntimeAssembly); } if (s_nativeDllResolveMap == null) { Interlocked.CompareExchange(ref s_nativeDllResolveMap, new ConditionalWeakTable <Assembly, DllImportResolver>(), null); } try { s_nativeDllResolveMap !.Add(assembly, resolver); // TODO-NULLABLE: Remove ! when compiler specially-recognizes CompareExchange for nullability } catch (ArgumentException) { // ConditionalWealTable throws ArgumentException if the Key already exists throw new InvalidOperationException(SR.InvalidOperation_CannotRegisterSecondResolver); } }
public static void SetResolve() { Console.WriteLine("Setting PInvoke Resolver"); DllImportResolver resolver = (string libraryName, Assembly asm, DllImportSearchPath? dllImportSearchPath) => { if (string.Equals(libraryName, NativeLibraryToLoad.InvalidName)) { if (dllImportSearchPath != DllImportSearchPath.System32) { Console.WriteLine($"Unexpected dllImportSearchPath: {dllImportSearchPath.ToString()}"); throw new ArgumentException(); } return(NativeLibrary.Load(NativeLibraryToLoad.Name, asm, null)); } return(IntPtr.Zero); }; NativeLibrary.SetDllImportResolver( Assembly.GetExecutingAssembly(), resolver); }
public static void ValidateSetDllImportResolver() { Console.WriteLine($"Running {nameof(ValidateSetDllImportResolver)}..."); Assembly assembly = Assembly.GetExecutingAssembly(); DllImportResolver resolver = Resolver.Instance.Callback; // Invalid arguments Assert.Throws <ArgumentNullException>(() => NativeLibrary.SetDllImportResolver(null, resolver)); Assert.Throws <ArgumentNullException>(() => NativeLibrary.SetDllImportResolver(assembly, null)); // No callback registered yet Assert.Throws <DllNotFoundException>(() => NativeSum(10, 10)); // Set a resolver callback NativeLibrary.SetDllImportResolver(assembly, resolver); // Try to set the resolver again on the same assembly Assert.Throws <InvalidOperationException>(() => NativeLibrary.SetDllImportResolver(assembly, resolver)); // Try to set another resolver on the same assembly DllImportResolver anotherResolver = (string libraryName, Assembly asm, DllImportSearchPath? dllImportSearchPath) => IntPtr.Zero; Assert.Throws <InvalidOperationException>(() => NativeLibrary.SetDllImportResolver(assembly, anotherResolver)); }
public static void SetDllImportResolver(Assembly assembly, DllImportResolver resolver) { if (assembly == null) { throw new ArgumentNullException(nameof(assembly)); } if (resolver == null) { throw new ArgumentNullException(nameof(resolver)); } if (!(assembly is RuntimeAssembly)) { throw new ArgumentException(SR.Argument_MustBeRuntimeAssembly); } if (s_nativeDllResolveMap == null) { Interlocked.CompareExchange(ref s_nativeDllResolveMap, new ConditionalWeakTable <Assembly, DllImportResolver>(), null); } try { s_nativeDllResolveMap !.Add(assembly, resolver); // TODO-NULLABLE: https://github.com/dotnet/roslyn/issues/26761 } catch (ArgumentException) { // ConditionalWealTable throws ArgumentException if the Key already exists throw new InvalidOperationException(SR.InvalidOperation_CannotRegisterSecondResolver); } }
/// <summary> /// Set a callback for resolving native library imports from an assembly. /// This per-assembly resolver is the first attempt to resolve native library loads /// initiated by this assembly. /// /// Only one resolver can be registered per assembly. /// Trying to register a second resolver fails with InvalidOperationException. /// </summary> /// <param name="assembly">The assembly for which the resolver is registered</param> /// <param name="resolver">The resolver callback to register</param> /// <exception cref="System.ArgumentNullException">If assembly or resolver is null</exception> /// <exception cref="System.ArgumentException">If a resolver is already set for this assembly</exception> public static void SetDllImportResolver(Assembly assembly, DllImportResolver resolver) { if (assembly == null) { throw new ArgumentNullException(nameof(assembly)); } if (resolver == null) { throw new ArgumentNullException(nameof(resolver)); } if (assembly is not RuntimeAssembly) { throw new ArgumentException(SR.Argument_MustBeRuntimeAssembly); } if (s_nativeDllResolveMap == null) { Interlocked.CompareExchange(ref s_nativeDllResolveMap, new ConditionalWeakTable <Assembly, DllImportResolver>(), null); } try { s_nativeDllResolveMap.Add(assembly, resolver); } catch (ArgumentException) { // ConditionalWeakTable throws ArgumentException if the Key already exists throw new InvalidOperationException(SR.InvalidOperation_CannotRegisterSecondResolver); } }
static void Main(string[] args) { #if LINUX // This is needed on linux as it will load the libs with // RTLD_GLOBAL instead ot RTLD_LOCAL. Otherwise bassmidi won't // work on linux unfortunately. // Moreover as we publish freeserf as a single file it will // be extracted to a temporary directory. So we will ensure // that the audio library is able to find bass at the right spot. DllImportResolver resolver = (string libraryName, Assembly asm, DllImportSearchPath? dllImportSearchPath) => DynamicLibrary.Load(libraryName, Program.ExecutablePath); string path = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location); string audioDllPath = Path.Combine(path, "Freeserf.Audio.dll"); // Set the resolver for our audio DLL NativeLibrary.SetDllImportResolver(Assembly.LoadFrom(audioDllPath), resolver); #endif try { using (var mainWindow = MainWindow.Create(args)) { if (mainWindow != null) { mainWindow.Run(); } } } catch (Exception ex) { Log.Error.Write(ErrorSystemType.Application, "Exception: " + ex.Message); } }
private static DllImportResolver StartPreLoading() { EnsureArchitectureIs64Bit(); DllImportResolver resolver = Resolve; Interlocked.Exchange(ref _isPreLoading, 1); return(resolver); }
private static GraphicsBackend UseSokolGfx(DllImportResolver resolver, GraphicsPlatform platform, GraphicsBackend?requestedBackend) { var backend = GetUseableGraphicsBackend(platform, requestedBackend); var rid = GetRuntimeIdentifier(platform); var extension = GetDynamicLibraryExtension(platform); var backendString = backend.ToString().ToLowerInvariant(); var libraryPrefix = platform == GraphicsPlatform.Windows ? string.Empty : "lib"; var libraryPath = $"runtimes/{rid}/native/{libraryPrefix}sokol_gfx-{backendString}.{extension}"; AddLibraryPath("sokol_gfx", libraryPath); NativeLibrary.SetDllImportResolver(typeof(PInvoke).Assembly, resolver); PreLoadLibrary("sokol_gfx", typeof(PInvoke)); return(backend); }
/// <summary> /// Set a callback for resolving native library imports from an assembly. /// This per-assembly resolver is the first attempt to resolve native library loads /// initiated by this assembly. /// /// Only one resolver can be registered per assembly. /// Trying to register a second resolver fails with InvalidOperationException. /// </summary> /// <param name="assembly">The assembly for which the resolver is registered</param> /// <param name="resolver">The resolver callback to register</param> /// <exception cref="System.ArgumentNullException">If assembly or resolver is null</exception> /// <exception cref="System.ArgumentException">If a resolver is already set for this assembly</exception> public static void SetDllImportResolver(Assembly assembly, DllImportResolver resolver) { ArgumentNullException.ThrowIfNull(assembly); ArgumentNullException.ThrowIfNull(resolver); if (assembly is not RuntimeAssembly) { throw new ArgumentException(SR.Argument_MustBeRuntimeAssembly); } if (s_nativeDllResolveMap == null) { Interlocked.CompareExchange(ref s_nativeDllResolveMap, new ConditionalWeakTable <Assembly, DllImportResolver>(), null); } if (!s_nativeDllResolveMap.TryAdd(assembly, resolver)) { throw new InvalidOperationException(SR.InvalidOperation_CannotRegisterSecondResolver); } }
public static void SetDllImportResolver(Assembly assembly, DllImportResolver resolver) { if (NativeLibraryType == null) { return; } var dllImportResolverType = typeof(DllImportSearchPath).Assembly .GetType("System.Runtime.InteropServices.DllImportResolver"); var setDllImportResolverMethod = NativeLibraryType .GetMethod( "SetDllImportResolver", BindingFlags.Public | BindingFlags.Static, null, new[] { typeof(Assembly), dllImportResolverType }, null ); setDllImportResolverMethod.Invoke(null, new object[] { assembly, Delegate.CreateDelegate(dllImportResolverType, resolver, "Invoke") }); }
public static int Main() { try { Assembly assembly = Assembly.GetExecutingAssembly(); DllImportResolver resolver = (string libraryName, Assembly asm, DllImportSearchPath? dllImportSearchPath) => { if (dllImportSearchPath != DllImportSearchPath.System32) { Console.WriteLine($"Unexpected dllImportSearchPath: {dllImportSearchPath.ToString()}"); throw new ArgumentException(); } return(NativeLibrary.Load("ResolveLib", asm, null)); }; DllImportResolver anotherResolver = (string libraryName, Assembly asm, DllImportSearchPath? dllImportSearchPath) => IntPtr.Zero; try { NativeSum(10, 10); Console.WriteLine("Exception expected: no callback registered yet"); return(101); } catch (DllNotFoundException) {} try { NativeLibrary.SetDllImportResolver(null, resolver); Console.WriteLine("Exception expected: assembly parameter null"); return(102); } catch (ArgumentNullException) { } try { NativeLibrary.SetDllImportResolver(assembly, null); Console.WriteLine("Exception expected: resolver parameter null"); return(103); } catch (ArgumentNullException) { } // Set a resolver callback NativeLibrary.SetDllImportResolver(assembly, resolver); try { // Try to set another resolver on the same assembly. NativeLibrary.SetDllImportResolver(assembly, anotherResolver); Console.WriteLine("Exception expected: Trying to register second resolver"); return(104); } catch (InvalidOperationException) { } if (NativeSum(10, 10) != 20) { Console.WriteLine("Unexpected ReturnValue from NativeSum()"); return(105); } } catch (Exception e) { Console.WriteLine($"Unexpected exception: {e.ToString()} {e.Message}"); return(106); } return(100); }
public static void SetDllImportResolver(Assembly assembly, DllImportResolver resolver) { lock (Resolvers) Resolvers.GetOrCreateValue(assembly).AddLast(resolver); }
private static GraphicsPlatform UseSDL2(DllImportResolver resolver) { var exportsToIgnore = new List <string>(); if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { AddLibraryPath("SDL2", "runtimes/win-x64/native/SDL2.dll"); } if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) { AddLibraryPath("SDL2", "runtimes/osx-x64/native/libSDL2.dylib"); AddLibraryPath("SDL2", "/Library/Frameworks/SDL2.framework/SDL2"); AddLibraryPath("SDL2", "/usr/local/lib/libSDL2.dylib"); } if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) { throw new NotImplementedException(); } // ReSharper disable StringLiteralTypo // exports required to ignore for macOS, needs more testing on other platforms exportsToIgnore.Add("SDL_WinRTGetDeviceFamily"); exportsToIgnore.Add("SDL_SetWindowsMessageHook"); exportsToIgnore.Add("SDL_iPhoneSetAnimationCallback"); exportsToIgnore.Add("SDL_iPhoneSetEventPump"); exportsToIgnore.Add("SDL_AndroidGetJNIEnv"); exportsToIgnore.Add("SDL_AndroidGetActivity"); exportsToIgnore.Add("SDL_IsAndroidTV"); exportsToIgnore.Add("SDL_IsChromebook"); exportsToIgnore.Add("SDL_IsDeXMode"); exportsToIgnore.Add("SDL_AndroidBackButton"); exportsToIgnore.Add("SDL_AndroidGetInternalStoragePath"); exportsToIgnore.Add("SDL_AndroidGetExternalStorageState"); exportsToIgnore.Add("SDL_GetAndroidSDKVersion"); exportsToIgnore.Add("SDL_WinRTRunApp"); exportsToIgnore.Add("SDL_UIKitRunApp"); exportsToIgnore.Add("SDL_HasARMSIMD"); exportsToIgnore.Add("SDL_GameControllerTypeForIndex"); exportsToIgnore.Add("SDL_GameControllerGetType"); exportsToIgnore.Add("SDL_GameControllerFromPlayerIndex"); exportsToIgnore.Add("SDL_GameControllerSetPlayerIndex"); exportsToIgnore.Add("SDL_JoystickFromPlayerIndex"); exportsToIgnore.Add("SDL_JoystickSetPlayerIndex"); exportsToIgnore.Add("SDL_LockTextureToSurface"); exportsToIgnore.Add("SDL_Metal_CreateView"); exportsToIgnore.Add("SDL_Metal_DestroyView"); exportsToIgnore.Add("SDL_SetTextureScaleMode"); exportsToIgnore.Add("SDL_GetTextureScaleMode"); // ReSharper restore StringLiteralTypo NativeLibrary.SetDllImportResolver(typeof(SDL).Assembly, resolver); PreLoadLibrary("SDL2", typeof(SDL), exportsToIgnore.ToArray()); // SDL2 platforms: https://github.com/spurious/SDL-mirror/blob/6b6170caf69b4189c9a9d14fca96e97f09bbcc41/src/SDL.c#L459 var platformString = SDL.SDL_GetPlatform(); var platform = platformString switch { "Windows" => GraphicsPlatform.Windows, "Mac OS X" => GraphicsPlatform.macOS, "Linux" => GraphicsPlatform.Linux, _ => GraphicsPlatform.Unknown }; return(platform); }
public static void SetDllImportResolver(Assembly assembly, DllImportResolver resolver) { }