-
Notifications
You must be signed in to change notification settings - Fork 4.9k
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
GeneratedComInterfaceAttribute can cause error CS0111: Type 'InterfaceImplementation' already defines a member called 'ABI_Blah' with the same parameter types #101242
Comments
This is not true. Function overloading is not valid in a COM interface. The MIDL compiler specifically doesn't support this - see here.
This is invalid in IDL, probably why the IDL for these interfaces aren't public. |
MIDL doesn't allow overloading but I don't think MIDL (or even IDL) has ever been strictly mandatory to do COM. And I kinda remember overloading was not prohibited by ODL/IDL (just by MIDL). Their purpose is to define binary contracts, not named one, so even the term "overloading" is irrelevant to COM interfaces, it's more an OOP (ie historically C++) term. I mean, saying you don't want to do because it's too weird is one thing, saying it's invalid in COM is another. Quite a number of headers in the SDK were never based on IDL (not only DWrite, dbgeng.h, dbdaoint.h, xaudio2.h etc.). |
It is invalid because it can't be expressed in C. The name of the function needs to be different or else during compilation there will be a redefinition of the same function. Yes, it can be express in C++, but that is an implementation detail that is often exploited because C is used far less often. However the expressibility of the contract must adhere to the lowest common denominator and in this case that is C. I'm not against adding support for this but we are going to hit several complex issue if/when we enable the export scenario. Meaning define in C# and generate IDL/unmanaged defintiions. The MIDL compiler, if I recall, adds a suffix in some cases to disambiguate. My gripe is trying to reconcile our potential approach with whatever the MIDL compiler does. |
You can say "ComWrappers source generator only supports MIDL constructs", but I find that a bit rough (hum... ok, I'll trade it for TLB generation back... deal?). COM has always been language-agnostic (it was historically even platform-agnostic), there's no notion of overloading in it since it's "only" a binary standard, talks about interface ids, vtable binary layouts, method orders and signatures, never about names (and so it doesn't even have to come up with mangled name algorithms like with C++). https://learn.microsoft.com/en-us/windows/win32/com/the-component-object-model
https://learn.microsoft.com/en-us/windows/win32/com/com-technical-overview#objects-and-interfaces
Is it officially specified somewhere that if a COM interface cannot be expressed in C, it's invalid? |
@smourier I agree with where you are going with this and your perspective is the same I typically have - COM is an ABI defining technology. However, that just isn't how it is used or thought about in practice. It is a specific implementation of an ABI and comes with a myriad of special cases that, when not followed, create complex support scenarios that are leveraged for clever and niche purposes. The .NET runtime's goal, as I see it, is to enable support for COM as defined by the suite of tooling that exists for COM on the Windows platform. This means tools like the MIDL compiler, regsvr32, et al are the source of truth and reflect what is expected from the COM ecosystem. Yes, the layout and order of COM vtable slots are technically all that matters and programming languages shouldn't be a concern. Yes, one can manually define their own We are closer than might appear. My biggest concern here is exposing niche features that are leveraged by teams that merely want a reference counting interop story so they reach for All this reduces to, sure this can be done in COM if one does a ton of manual work and avoids using the most common tools. The DirectDraw/Direct2D/Direct3D APIs have well-maintained managed projections like Win2D and TerraFx. If this becomes a blocking issue for other APIs, lets reconsider it, but for now I'd like to avoid continuing down the path of adding these sorts of features when the workaround is so simple. |
Description
When using .NET8's GeneratedComInterfaceAttribute, we cannot define a COM interface with two methods with the same name if they share a "similar" signature (not sure exactly of what type of parameter causes it but with different COM interface parameters it fails), it raises CS0111: Type 'InterfaceImplementation' already defines a member called 'ABI_Blah' with the same parameter types.
Reproduction Steps
Consider this simple .NET 8 project:
And these interface definitions:
Expected behavior
It should just compile fine.
Note this type of interface is perfectly valid in COM, here is a Microsoft one https://learn.microsoft.com/en-us/windows/win32/api/dwrite_3/nn-dwrite_3-idwritegdiinterop1 defined like this:
Actual behavior
Building creates this error
E:\temp\ConsoleApp6.Program.IFace1.cs(93,25,93,33): error CS0111: Type 'InterfaceImplementation' already defines a member called 'ABI_Blah' with the same parameter types
Regression?
I don't think so since GeneratedComInterfaceAttribute is pretty new.
Known Workarounds
We can just rename IFace's second Blah with something else that doesn't conflict as COM names are not technically important but this raises lots of other issues, especially with .NET where names are.
Configuration
.NET 8.0.4 (tested on x64 but I don't think it's relevant here).
Other information
No response
The text was updated successfully, but these errors were encountered: