AaronRobinsonMSFT / DNNE

Prototype native exports for a .NET Assembly.
MIT License
394 stars 41 forks source link

InvalidCastException only occurs through DNNE #169

Closed jgcodes2020 closed 1 year ago

jgcodes2020 commented 1 year ago

I'm writing an Avalonia-based GUI for a plugin with DNNE.

Recently, I tried to add Material.Icons.Avalonia, and while running the GUI as an application works, it throws an exception when loaded via DNNE:

Unhandled exception. System.InvalidCastException: Unable to cast object of type 'Avalonia.Controls.ResourceDictionary' to type 'Avalonia.Controls.IResourceDictionary'.
   at Avalonia.Markup.Xaml.Styling.ResourceInclude.get_Loaded() in /_/src/Markup/Avalonia.Markup.Xaml/Styling/ResourceInclude.cs:line 55
   at Material.Icons.Avalonia.MaterialIconStyles.AddOwner(IResourceHost owner)
   at Avalonia.Styling.Styles.InternalAdd(IList items, IResourceHost owner) in /_/src/Avalonia.Base/Styling/Styles.cs:line 265
   at Avalonia.Styling.Styles.OnCollectionChanged(Object sender, NotifyCollectionChangedEventArgs e) in /_/src/Avalonia.Base/Styling/Styles.cs:line 301
   at Avalonia.Collections.AvaloniaList`1.NotifyAdd(T item, Int32 index) in /_/src/Avalonia.Base/Collections/AvaloniaList.cs:line 700
   at Avalonia.Collections.AvaloniaList`1.Add(T item) in /_/src/Avalonia.Base/Collections/AvaloniaList.cs:line 205
   at Avalonia.Styling.Styles.Add(IStyle item) in /_/src/Avalonia.Base/Styling/Styles.cs:line 165
   at TinCan.NET.App.!XamlIlPopulate(IServiceProvider , App ) in /home/jgcodes/Documents/Code/C#/TinCan.NET/TinCan.NET/App.axaml:line 7
   at TinCan.NET.App.!XamlIlPopulateTrampoline(App )
   at TinCan.NET.App.Initialize() in /home/jgcodes/Documents/Code/C#/TinCan.NET/TinCan.NET/App.axaml.cs:line 13
   at Avalonia.AppBuilder.Setup() in /_/src/Avalonia.Controls/AppBuilder.cs:line 263
   at Avalonia.AppBuilder.SetupWithLifetime(IApplicationLifetime lifetime) in /_/src/Avalonia.Controls/AppBuilder.cs:line 162
   at Avalonia.ClassicDesktopStyleApplicationLifetimeExtensions.StartWithClassicDesktopLifetime(AppBuilder builder, String[] args, ShutdownMode shutdownMode) in /_/src/Avalonia.Controls/ApplicationLifetimes/ClassicDesktopStyleApplicationLifetime.cs:line 213
   at TinCan.NET.Plugin.<>c.<RomOpen>b__5_0() in /home/jgcodes/Documents/Code/C#/TinCan.NET/TinCan.NET/Plugin.cs:line 87
   at System.Threading.Thread.StartHelper.Callback(Object state)
   at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state)
--- End of stack trace from previous location ---
   at System.Threading.Thread.StartCallback()

Process finished with exit code 134.

Here's the affected project: https://github.com/jgcodes2020/TinCan.NET, I'm not sure how a break could only occur using DNNE.

jkoritzinsky commented 1 year ago

I can't see your repro, can you share it or upload a zip of it?

jgcodes2020 commented 1 year ago

I can't see your repro, can you share it or upload a zip of it?

Should be public now.

jgcodes2020 commented 1 year ago

Doing some further testing, the issue also only seems to occur when the plugin is called indirectly through a .NET application. Using a native client to the plugin (https://github.com/mupen64plus/mupen64plus-ui-console) seems to resolve the issue.

Perhaps this has to do with both host and plugin running the same assemblies.

jgcodes2020 commented 1 year ago

I've looked through the sample code. It seems I'm not calling preload_runtime. Does this affect anything? @jkoritzinsky

AaronRobinsonMSFT commented 1 year ago

I've looked through the sample code. It seems I'm not calling preload_runtime. Does this affect anything?

Nope, that is called when the first export is executed unless the user has already called it - see documentation in header file.

https://github.com/AaronRobinsonMSFT/DNNE/blob/cd55d290c56c022a7a73b48f0ecf232546bee6e3/src/platform/dnne.h#L94-L99

AaronRobinsonMSFT commented 1 year ago

Perhaps this has to do with both host and plugin running the same assemblies.

@jgcodes2020 I believe you are hitting an issue with AssemblyLoadContexts. It is a common problem with extension points in .NET and tools like DNNE. See issues like https://github.com/AaronRobinsonMSFT/DNNE/issues/154 or https://github.com/AaronRobinsonMSFT/DNNE/issues/115. There is also a detailed description of ALCs here.

AaronRobinsonMSFT commented 1 year ago

@jgcodes2020 I'm going to close this issue for now as it appears this is an ALC issue. Please let us know if you are still blocked or found data that indicates there is a different root issue.