Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Consider specifying a given architecture for APIs when targetting AnyCPU #882

Open
JeremyKuhne opened this issue Mar 11, 2023 · 3 comments
Labels
enhancement New feature or request partner

Comments

@JeremyKuhne
Copy link
Member

Is your feature request related to a problem? Please describe.
Windows Forms needs to build for AnyCPU so customers can continue to build for AnyCPU. Some Win32 APIs are not really portable (notably the Pack = 1 versions), but for WinForms internal purposes the x86/x64 definitions are equivalent.

Describe the solution you'd like
The ability to specify in the settings json that we want specific listed APIs to come from a given architecture. This would also allow us to address things like Get/SetWindowLong/Ptr.

Describe alternatives you've considered
The only real alternative is to manually define things- which is very much not desirable. :)

Additional context
I spoke with @tannergooding a bit about this and he helped me understand this is not something we can really deal with at the Win32Metadata level as it has to allow for all consumers (can't presume .NET) and uses of the data structures (composition within other types, etc.).

@JeremyKuhne JeremyKuhne added the enhancement New feature or request label Mar 11, 2023
@tannergooding
Copy link
Member

In TerraFX, I ended up dealing with many of these "manually".

For example, I explicitly define custom versions of GetWindowLongPtrA/W which handles the difference between the 32-bit and 64-bit versions.

Another example is SP_DEVINFO_DATA where I've defined a helper type that unions the 32-bit vs 64-bit differences.

Such a type is "portable" for the purposes of a P/Invoke that takes this type directly. It is not however usable "everywhere". It cannot for example be used to define SP_PROPSHEETPAGE_REQUEST.

Instead we have to define 32/64-bit variants of this struct as well and expose a higher level wrapper there as well. A user would likely have to abstract it themselves for any of their own structures they define it in. This isn't "common" so it isn't normally an issue. -- There also come with a few quirks, such as not being able to use sizeof(T), etc.

@AArnott
Copy link
Member

AArnott commented Mar 11, 2023

Windows Forms needs to build for AnyCPU so customers can continue to build for AnyCPU.

Many assemblies in .NET are built architecture specific. In fact all of them since R2R makes them so. The requirement is that the reference assembly target AnyCPU so that customers can target AnyCPU with their apps. WinForms could do the same (and as much as you're hitting arch-specific APIs, maybe it should). I understand that the work to enable this in the multi-repo build system would be complex, so maybe that's not the right call. But let's be clear about the requirement so we consider all options.

I'm willing to think through the ramifications of the proposal, but it may not be trivial. And it may be far more complex for the user than they realize. For example, if they state they want a single struct to be declared from its x64 metadata, but that struct references other structs that are also x64, you may end up with many x64 structs, and not realize when you're using one that it isn't actually safe in x86 or arm64 processes.

This might not 'just work' for GetWindowLongPtr either. In past conversations on that topic, I thought we concluded very special code would have to be emitted. @tannergooding's example code seems to confirm that.

@JeremyKuhne
Copy link
Member Author

To be clear, this is an expediency. It is an "unsafe" feature that allows consuming the metadata. We have no choice but to keep WinForms AnyCPU and that forces manual definition of a number of things. We can iterate to move common abstractions (such as Set/GetWindowLong in CsWin32.

Perhaps we can take a page from the .NET libraries and have these in the settings as "UnsafeAsX64" and "UnsafeAsX86". Could potentially also fail out on given APIs when they're given a suitable wrap in CsWin32?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request partner
Projects
None yet
Development

No branches or pull requests

3 participants