CppSharp icon indicating copy to clipboard operation
CppSharp copied to clipboard

CppSharp generates incorrect bindings for SDL_Event

Open aarroyoc opened this issue 8 years ago • 2 comments

CppSharp with SDL generates the wrong bindings.

This is the equivalent C code:

SDL_Event event;
while(SDL_WaitEvent(&event))
{
    if(e.type = SDL_QUIT)
        exit(0);
}

One should expect to get it working with something like this:

SDL.SDL_Event e = new SDL.SDL_Event();
while(SDL.SDL_WaitEvent(e))
{
    if(e.Type == (uint)SDL.SDL_EventType.SDL_QUIT)
        System.Environment.Exit(0);
}

But SDL.SDL_Event is a C# struct, it can't change

Function binding:

[SuppressUnmanagedCodeSecurity]
[DllImport("SDL2", CallingConvention = global::System.Runtime.InteropServices.CallingConvention.Cdecl,EntryPoint="SDL_WaitEvent")]
internal static extern int SDL_WaitEvent(global::System.IntPtr @event);

public static int SDL_WaitEvent(global::SDL.SDL_Event @event)
{
    var ____arg0 = @event.__Instance;
    var __arg0 = new global::System.IntPtr(&____arg0);
    var __ret = __Internal.SDL_WaitEvent(__arg0);
    return __ret;
}

SDL_Event generated struct:

public unsafe partial struct SDL_Event
{
    [StructLayout(LayoutKind.Explicit, Size = 56)]
    public partial struct __Internal
    {
        [FieldOffset(0)]
        internal uint type;

        [FieldOffset(0)]
        internal global::SDL.SDL_CommonEvent.__Internal common;

        [FieldOffset(0)]
        internal global::SDL.SDL_WindowEvent.__Internal window;

        [FieldOffset(0)]
        internal global::SDL.SDL_KeyboardEvent.__Internal key;

        [FieldOffset(0)]
        internal global::SDL.SDL_TextEditingEvent.__Internal edit;

        [FieldOffset(0)]
        internal global::SDL.SDL_TextInputEvent.__Internal text;

        [FieldOffset(0)]
        internal global::SDL.SDL_MouseMotionEvent.__Internal motion;

        [FieldOffset(0)]
        internal global::SDL.SDL_MouseButtonEvent.__Internal button;

        [FieldOffset(0)]
        internal global::SDL.SDL_MouseWheelEvent.__Internal wheel;

        [FieldOffset(0)]
        internal global::SDL.SDL_JoyAxisEvent.__Internal jaxis;

        [FieldOffset(0)]
        internal global::SDL.SDL_JoyBallEvent.__Internal jball;

        [FieldOffset(0)]
        internal global::SDL.SDL_JoyHatEvent.__Internal jhat;

        [FieldOffset(0)]
        internal global::SDL.SDL_JoyButtonEvent.__Internal jbutton;

        [FieldOffset(0)]
        internal global::SDL.SDL_JoyDeviceEvent.__Internal jdevice;

        [FieldOffset(0)]
        internal global::SDL.SDL_ControllerAxisEvent.__Internal caxis;

        [FieldOffset(0)]
        internal global::SDL.SDL_ControllerButtonEvent.__Internal cbutton;

        [FieldOffset(0)]
        internal global::SDL.SDL_ControllerDeviceEvent.__Internal cdevice;

        [FieldOffset(0)]
        internal global::SDL.SDL_AudioDeviceEvent.__Internal adevice;

        [FieldOffset(0)]
        internal global::SDL.SDL_QuitEvent.__Internal quit;

        [FieldOffset(0)]
        internal global::SDL.SDL_UserEvent.__Internal user;

        [FieldOffset(0)]
        internal global::SDL.SDL_SysWMEvent.__Internal syswm;

        [FieldOffset(0)]
        internal global::SDL.SDL_TouchFingerEvent.__Internal tfinger;

        [FieldOffset(0)]
        internal global::SDL.SDL_MultiGestureEvent.__Internal mgesture;

        [FieldOffset(0)]
        internal global::SDL.SDL_DollarGestureEvent.__Internal dgesture;

        [FieldOffset(0)]
        internal global::SDL.SDL_DropEvent.__Internal drop;

        [FieldOffset(0)]
        internal fixed byte padding[56];

        [SuppressUnmanagedCodeSecurity]
        [DllImport("SDL", CallingConvention = global::System.Runtime.InteropServices.CallingConvention.Cdecl,
            EntryPoint="??0SDL_Event@@QEAA@AEBT0@@Z")]
        internal static extern global::System.IntPtr cctor(global::System.IntPtr instance, global::System.IntPtr _0);
    }

aarroyoc avatar Oct 03 '17 21:10 aarroyoc

@aarroyoc could you build C++# from source and debug? The problem is that SDL_Event is generated as a structure rather than a class, you just need to see why.

ddobrev avatar Oct 04 '17 12:10 ddobrev

Well , I can reproduce this issue (it's still valid in 2022) . If anyone has an elegant way to fix it (not on the native side) , I will be more than happy to hear about it.

elix22 avatar May 18 '22 08:05 elix22

SDL_Event is generated as a struct, because it's a union. I think you need to manually configure the parameter as an out parameter via ctx.SetFunctionParameterUsage("SDL_PollEvent", 1, ParameterUsage.Out); in ILibrary.Preprocess. After that and #1775 it should work (at least it does for me)!

Saalvage avatar Oct 18 '23 16:10 Saalvage