Skip to content

NativeAOT reflection-free support #960

Closed
@kant2002

Description

@kant2002

I did try to run Silk.Net tutorials in reflection-free mode, and I hit couple issues. Before jumping to that agressive mode, let me explain what I have to do to make app run in NativeAOT with reflection.

Right now I have to perform 2 steps.

  1. Update Microsoft.Extensions.DependencyModel to latest version.
<PackageReference Include="Microsoft.Extensions.DependencyModel" Version="6.0.0" />
  1. Manually register platforms
Silk.NET.Input.Sdl.SdlInput.RegisterPlatform();
Silk.NET.Input.Glfw.GlfwInput.RegisterPlatform();

I was hoping that I should just register platforms, but due to how native libraries loaded, which somehow rely on Microsoft.Extensions.DependencyModel I have to update that dependency. That part was confusing.

Back to reflection-free mode. After successfully run app in NativeAOT if I run without reflection I receive following error

Unhandled Exception: EETypeRva:0x00288098: Reflection_Disabled
   at Internal.Reflection.RuntimeTypeInfo.get_Name() + 0x72
   at Silk.NET.Windowing.Window.<>c.<get_PlatformsStr>b__12_0(IWindowPlatform) + 0x1a
   at System.Linq.Enumerable.SelectListIterator`2.MoveNext() + 0x5d
   at System.String.Join(String, IEnumerable`1) + 0x182
   at Silk.NET.Windowing.Window.get_PlatformsStr() + 0x71
   at Silk.NET.Windowing.Window.get_NoPlatformException() + 0x1e
   at Silk.NET.Windowing.Window.Create(WindowOptions) + 0x199
   at Tutorial.Program.Main(String[]) + 0xb9
   at Tutorial!<BaseAddress>+0x1fe8e3

That's because name of platform comes from GetType() here.

x => x.GetType().Name + (x.IsViewOnly ? " - view only" :
!x.IsApplicable ? " - not applicable" : string.Empty)

I workaround this by providing separate interface IWindowPlatformName which has just one property PlatformName and use that to provide names for platforms.
After that I hit this exception

Unhandled Exception: EETypeRva:0x00288D10: Couldn't find a suitable window platform. (SdlPlatform - not applicable, GlfwPlatform - not applicable) https://dotnet.github.io/Silk.NET/docs/hlu/troubleshooting.html
   at Silk.NET.Windowing.Window.Create(WindowOptions) + 0x1a1
   at Tutorial.Program.Main(String[]) + 0xb9
   at Tutorial!<BaseAddress>+0x1fe9c3

which closely remind me issue with DependencyModel which I have in regular NativeAOT app.
Hmm. After I start writing issue, I find a way to locally build project, and try to hack around to test support. What I found is that DefaultPathResolver can helps to avoid issues in reflection-free mode, but at cost of having this ugly workaround

var resolver = (Silk.NET.Core.Loader.DefaultPathResolver)Silk.NET.Core.Loader.PathResolver.Default;
resolver.Resolvers = new()
{
    Silk.NET.Core.Loader.DefaultPathResolver.PassthroughResolver,
    Silk.NET.Core.Loader.DefaultPathResolver.LinuxVersioningResolver,
    Silk.NET.Core.Loader.DefaultPathResolver.MacVersioningResolver,
    Silk.NET.Core.Loader.DefaultPathResolver.BaseDirectoryResolver,
    Silk.NET.Core.Loader.DefaultPathResolver.MainModuleDirectoryResolver,
    //Silk.NET.Core.Loader.DefaultPathResolver.RuntimesFolderResolver,
    Silk.NET.Core.Loader.DefaultPathResolver.NativePackageResolver,
};

Notice that only failure in Silk.NET.Core.Loader.DefaultPathResolver.RuntimesFolderResolver completely crash resolution process. So maybe If wrap each resolution process in try/catch that allow some resilency for unknown cases like reflection-free mode.
I thinking about wrapping content of foreach loop here.

foreach (var resolver in Resolvers)
{
if (candidates.Count == 0 || resolver == PassthroughResolver)
{
candidates.AddRange(resolver.Invoke(name));
}
else
{
for (var i = 0; i < candidates.Count; i++)
{
var oldCnt = candidates.Count;
candidates.InsertRange(i + 1, resolver.Invoke(candidates[i]));
i += candidates.Count - oldCnt;
}
}
}

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions

    pFad - Phonifier reborn

    Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

    Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


    Alternative Proxies:

    Alternative Proxy

    pFad Proxy

    pFad v3 Proxy

    pFad v4 Proxy