corert
corert copied to clipboard
MarshalDelegate does not seem to work
Hello,
I managed to build my FNA (XNA implementation, like MonoGame) game with CoreRT, but there is a problem with Marshal.GetDelegateForFunctionPointer.
Unhandled Exception: Microsoft.Xna.Framework.Graphics.NoSuitableGraphicsDeviceException: GRAPHICS DRIVER IS EXTREMELY BROKEN! Microsoft.Xna.Framework.Graphics.OpenGLDevice+GetString is missing delegate marshalling data. To enable delegate marshalling data, add a MarshalDelegate directive to the application rd.xml file. For more information, please visit http://go.microsoft.com/fwlink/?LinkID=393965 at Microsoft.Xna.Framework.Graphics.OpenGLDevice.LoadGLGetString() + 0xd1 at Microsoft.Xna.Framework.Graphics.OpenGLDevice..ctor(PresentationParameters, GraphicsAdapter) + 0x2f3 at Microsoft.Xna.Framework.SDL2_FNAPlatform.CreateGLDevice(PresentationParameters, GraphicsAdapter) + 0x62 at Microsoft.Xna.Framework.Graphics.GraphicsDevice..ctor(GraphicsAdapter, GraphicsProfile, PresentationParameters) + 0x15c at Microsoft.Xna.Framework.GraphicsDeviceManager.Microsoft.Xna.Framework.IGraphicsDeviceManager.CreateDevice() + 0xda at Microsoft.Xna.Framework.GraphicsDeviceManager.get_GraphicsDevice() + 0x16 at Microsoft.Xna.Framework.Game.InitializeGraphicsService() + 0x68 at Microsoft.Xna.Framework.Game.DoInitialize() + 0x19 at Microsoft.Xna.Framework.Game.Run() + 0x1e at FNA CoreRT Test!<BaseAddress>+0x1bd266
So I added this rd.xml to the project :
<Directives> <Application> <Assembly Name="FNA" MarshalDelegate="Required All"> <Type Name="Microsoft.Xna.Framework.Graphics.OpenGLDevice+GetString" MarshalDelegate="Required All"> </Type> </Assembly> </Application> </Directives>
But the problem still persists.
I attached a sample project with this issue. FNA CoreRT Test.zip
CoreRT does not yet read the directives for delegate marshaling from rd.xml. Here are the workarounds that should work today:
- Mark the delegates that are used with interop with
UnmanagedFunctionPointerAttributeor - Use generic overloads of
Marshal.GetFunctionPointerForDelegateandMarshal.GetDelegateForFunctionPointermethods. E.g. replace(MyDelegate)Marshal.GetFunctionPointerForDelegate(MyMethod, typeof(MyDelegate))withMarshal.GetFunctionPointerForDelegate<MyDelegate>(MyMethod). MonoGame for .NET Core/CoreRT has the same workaround here: https://github.com/cra0zy/MonoGame/commit/dc44fc2ca8de754c9039dab6f7a71558c177aa69#diff-2590f64f9edb856d8dfa1f1000e5f84aR1456
That's working, thanks a lot !
Maybe you should consider changing the error message by what you just answered, instead of suggesting changing something in the rd.xml that does not work :-P
Is there any work being done to get CoreRT to actually read the marshaller directives from rd.xml?
Is there any work being done to get CoreRT to actually read the marshaller directives from rd.xml?
Not at this point. Generation of marshalling data is currently driven purely by code being compiled. We do want to do more separation, so that generation of marshalling is controlled through a pluggable component. #6063 is a similar problem.
Here are the workarounds that should work today:
Mark the delegates that are used with interop with
UnmanagedFunctionPointerAttributeorUse generic overloads of
Marshal.GetFunctionPointerForDelegate
MonoGame was still crashing on Mac OS X (.NET Core 2.1 and ILCompiler 1.0.0-alpha-28229-02) giving similar symptoms, despite already using the second workaround. Adding UnmanagedFunctionPointerAttribute(CallingConvention.Cdecl) on top of that (that is, using both workarounds at the same time, which was seemingly unnecessary on Windows and Linux) fixed the issue.