Description
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.
- Update
Microsoft.Extensions.DependencyModel
to latest version.
<PackageReference Include="Microsoft.Extensions.DependencyModel" Version="6.0.0" />
- 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.
Silk.NET/src/Windowing/Silk.NET.Windowing.Common/Window.cs
Lines 40 to 41 in 77314f0
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.
Silk.NET/src/Core/Silk.NET.Core/Loader/DefaultPathResolver.cs
Lines 144 to 159 in 77314f0