Esempio n. 1
0
        /// <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);
            }
        }
Esempio n. 2
0
    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);
    }
Esempio n. 3
0
    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));
    }
Esempio n. 4
0
        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);
            }
        }
Esempio n. 5
0
        /// <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);
            }
        }
Esempio n. 6
0
        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);
            }
        }
Esempio n. 7
0
    private static DllImportResolver StartPreLoading()
    {
        EnsureArchitectureIs64Bit();
        DllImportResolver resolver = Resolve;

        Interlocked.Exchange(ref _isPreLoading, 1);
        return(resolver);
    }
Esempio n. 8
0
    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);
    }
Esempio n. 9
0
        /// <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);
            }
        }
Esempio n. 10
0
        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")
            });
        }
Esempio n. 11
0
    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);
    }
Esempio n. 12
0
 public static void SetDllImportResolver(Assembly assembly, DllImportResolver resolver)
 {
     lock (Resolvers)
         Resolvers.GetOrCreateValue(assembly).AddLast(resolver);
 }
Esempio n. 13
0
    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);
    }
Esempio n. 14
0
 public static void SetDllImportResolver(Assembly assembly, DllImportResolver resolver)
 {
 }