SFML / SFML.Net

Official binding of SFML for .Net languages

Home Page:https://www.sfml-dev.org

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

ContextSettings Signature Mismatch (MarshalDirectiveException)

Rosst0pher opened this issue · comments

commented

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.

commented

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.

commented

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.

commented

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.

commented

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.

commented

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.

commented

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.

commented

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?