-
Notifications
You must be signed in to change notification settings - Fork 2.7k
Support function pointers in field marshalers #28046
Support function pointers in field marshalers #28046
Conversation
@AaronRobinsonMSFT, is it worth updating the customer impact from:
Since they "work" just fine from managed code, its only when trying to use them with interop or when relying on the layout to actually be |
@tannergooding Yes. That clarification is important - thanks. Updated. |
I am sorry but I do not think this makes the bar for backport to 3.1. Feel free to do bar check with servicing ship room. We are focused on making sure that the latest .NET Runtime works well with latest C#. If you want to use latest C# with older .NET Runtimes, your experience will vary. We are not servicing the older runtimes nor going out of our way to create special OOB packages to make it work better. For reference, here is a similar discussion about nullability: dotnet/runtime#30493 (comment) |
@jkotas is that going to be true when the latest .NET Runtime isn't an LTS? I'd understand not supporting 3.0 or 2.2 or 2.1 from that perspective, but given 3.1 is the latest LTS it would be nice to have libraries working on "latest LTS" + "latest runtime"... |
You can make the libraries work by using the workaround, on all .NET Core 2.1, 3.1 and .NET Framework. |
Fair enough. Although I think I'd rather just drop netcoreapp3.1 support than have to add casts to the ~14,000 function pointers that are in TerraFX.Interop.Windows COM VTBLs 😄. It also looks like You need to use |
@jkotas That is okay. This didn't require a lot to investigate nor fix so figured I would toss it up here and see. I would like to support it, but understand since a workaround exists that that may reduce the need for servicing. Will defer to ship room bar check. |
FWIW, it would better to avoid the strongly typed vtables and do the cast of the slot to the right type inline, e.g.:
The strongly types vtables are unnecessary overhead and work poorly with IL linking (keeping around stuff that can be trimmed away). I assume that you are autogenerating this stuff and not typing all this manually, and so having slot numbers inline is not a big deal. |
I think I would push back on that. Part of the auto-generating approach is producing code that is debuggable and easier to diagnose. The above code snippet is not fun in a debugger at all. Not that is should be the highest priority, but being able to debug some of this is a benefit we should consider. Do we know how much are we actually saving in the example or in practice by removing all these types? |
I logged terrafx/terrafx.interop.windows#83 to investigate. It certainly hurts readability. The bindings are all autogenerated, including wrapper methods to fixup bits like struct returns and to handle the |
I do not think that the debugging experience is significantly different between strongly typed vtables vs. inlined slots. You can make it easier to read by auto-generating this into multiple lines, introduce a local for the function pointer, etc.
The strongly typed vtables increase the number of types required to make a thing work by 2x. The extra overhead from keeping extra stuff around with IL linker on can be arbitrary high. |
So my interpretation of this was wrong. The point is by defining That is a convincing argument for not needing it - I'm on board. |
This argument was used a lot during MCG development. What happened in practice was:
The result is that the auto-generators end up favoring efficiency over readability when there is a choice. |
That just leaves cases like Having this be |
Fixes dotnet/runtime#37295
This was fixed in .NET 5 when field marshalling was completely rewritten.
Customer Impact
Users will be unable to have function pointers as fields in structs that are used in interop scenarios. Function pointers are now supported in the C# language.
Workaround
This can naturally be worked around by using
IntPtr
,UIntPtr
,void*
,nint
, ornuint
as the field and then casting to the appropriate function pointer type at the usage site in managed code. This would severely degrade the UX for usage of function pointers though.Regression?
No. This is supporting a new C# feature and previous .NET runtimes never tested/supported this scenario.
Testing
Validated both 32 and 64 bit struct of the field marshalling scenario. This follows the same behavior as a
void*
pointer so no new functionality is added just reuse of an existing code path for a new type.Risk
Low.
/cc @tannergooding @333fred @jkoritzinsky @jkotas