ContextSettings Signature Mismatch (MarshalDirectiveException)
Rosst0pher opened this issue · comments
I just upgraded to SFML 2.5 and found attempting to read Settings property on a RenderWindow throws a MarshalDirectiveException with the message Method's type signature is not PInvoke compatible
Here's my code to reproduce.
class Program
{
static void Main(string[] args)
{
var running = true;
using (var window = new RenderWindow(VideoMode.DesktopMode, "Test"))
{
window.Closed += (sender, eventargs) => running = false;
var settings = window.Settings;
while (running)
{
window.WaitAndDispatchEvents();
window.Clear();
window.Display();
}
}
}
}
I had a dive into the source and think this is because in CSFML the SRgbCapable member of ContextSettings is an sfBool which is Int32 and .NET is expecting a boolean.
Just to test my conclusion I swapped out SRgbCapable in ContextSettings to be an Int instead of a bool and that resolves the issue.
@eXpl0it3r Where would be the incentive to fix this? Would ContextSettings struct be changed in CSFML or in SFML.Net?
What's the underlying type in C++? If it's a mismatch between SFML and CSFML, fix it in CSFML. If it's a mismatch between CSFML and SFML.Net, fix it in SFML.Net.
in both C++ and C# its bool and in C its sfBool (Int)
I see sfBool is used everywhere in place of bool in CSFML so I'd be unsure if changing it for this one instance would be desired.
Ah I see. I'll have to investigate how to resolve this. It seems like for functions we simply use bool
in the import statements, not sure if a similar thing can be done for ContextSettings struct.
Should probably be able to do something with the [MarshalAs(...)]
attribute on the SRgbCapable property.
So I was expecting [MarshalAs(UnmanagedType.Bool)]
described as a 4-byte boolean to resolve this but I still get the the same exception for some reason.
@rfuge A quick look over things suggests that UnmanagedType.I4 would be the correct Marshal Type. If you're already set up to test it, give that a whack and let us know if it resolves it. If not, I can check shortly myself.
It really doesn't like that one and I got a different exception this time.
System.TypeLoadException: 'Cannot marshal field 'SRgbCapable' of type 'SFML.Window.ContextSettings': Invalid managed/unmanaged type combination (booleans must be paired with I1, U1, Bool, or VariantBool).'
From that error I tried both I1 and U1 too though I don't think they would make sense anyway, they don't work either.
I'm wondering if this might be solely down to the discrepancy in the size of the structs between CSFML and SFML.Net, given that swapping out the bool with a Int in SFML.Net resolves the issue.
Oh, almost definitely. Just trying to think what might be the best way to resolve it. Switching to int is a solution, but it's not pretty, so before I agree to make that switch, I want to evaluate other possible answers.
Specifically, System.Boolean is not a blittable type within a struct, thereby making the struct non-blittable, meaning that the marshaler can't deal with it.
The only other solution I can think of without swapping the field type or changing CSFML is to add a new type to SFML.Net to reflect the C counterpart if it seems necessary... like a IntBool type.
I'm not able to replicate the change to int solving the exception.
I'm testing with a .NET Core app with SFML in as local dependencies.
All I've changed is SRgbCapable from bool
to int
and in the constructor
SRgbCapable = sRgbCapable ? 1 : 0;
My big project I upgraded is a .NET Framework app and that also works with this change.
I had something derpy going on with my build setup before. I've implement the int conversion + a property called sRGBCapable in PR #167
Fixed by #168
This was resolved 3 months ago but I don't see that any release has been done since then to get this to NuGet so we can use it. How can we get the fix without having to build and ship the library ourselves?