alesliehughes / monoDX

Managed DirectX replacement
MIT License
5 stars 5 forks source link

Applications expect parameterless constructors for structures #12

Closed madewokherd closed 2 years ago

madewokherd commented 2 years ago

After some additional work on the Sega Rally launcher, I now get: Method not found: void Microsoft.DirectX.Direct3D.DisplayMode..ctor()

DisplayMode is a structure. Adding a parameterless constructor in C# is an error. This was probably an accident due to Managed DirectX not being written in C#. (Apparently, this is allowed in C# 10, but in Mono we currently only have access to C# 9.)

Many other structures have parameterless constructors according to MSDN, and this isn't even the only one used by this particular launcher.

Note that there's no guarantee that any constructor will be called. It's not clear to me yet whether they actually do anything or just leave fields zeroed.

A possible solution would be to add internal static methods named something like ParameterlessInit. We could then have a post-process step that adds a new parameterless constructor to any structure defining this method, which just calls it.

Before I start working on this, would you be willing to accept an approach like this? Would you want the post-processor to be included in monoDX? I wouldn't be able to add that step to the .csproj files.

madewokherd commented 2 years ago

Maybe for future-proofing we could do something like

#if CSHARP10
    public DeviceList()
#else
    internal void ParameterlessInit()
#endif
    {
        ...
    }
madewokherd commented 2 years ago

I don't want to be held up too long, so I guess I'll try putting something together with Mono.Cecil.

alesliehughes commented 2 years ago

My understand, is that a default constructor was implicit for structures. I think the caveat was that the structure was need to be used somewhere DisplayMode xxx = new DisplayMode()

It's been awhile since I seen this error, so I have abit of brain fog in this regard.

madewokherd commented 2 years ago

Yes, that's how it normally works. C# will not let you create the constructor, and it will implicitly zero out the structure if you try to call it.

However, there is apparently nothing in the runtime that prevents an explicit constructor like that from existing, Managed DirectX does have them, and Sega Rally does link to them. Because the feature that implicitly creates a default constructor is part of C#, not part of the runtime itself, and does not add the constructor to the image, this causes an error currently.

madewokherd commented 2 years ago

Fixed by #14.