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

IDispatch interface is not generated #861

Closed
jnm2 opened this issue Feb 18, 2023 · 8 comments · Fixed by #865
Closed

IDispatch interface is not generated #861

jnm2 opened this issue Feb 18, 2023 · 8 comments · Fixed by #865
Labels
bug Something isn't working

Comments

@jnm2
Copy link
Contributor

jnm2 commented Feb 18, 2023

Actual behavior

Generation of this interface seems to be skipped.

image

Expected behavior

Something like this:

[ComImport]
[Guid("00020400-0000-0000-C000-000000000046")]
[InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
private interface IDispatch
{
}

Repro steps

  1. NativeMethods.txt content:
IDispatch
  1. NativeMethods.json content (if present):
  1. Any of your own code that should be shared?
_ = typeof(IDispatch).GUID;

Context

  • CsWin32 version: 0.2.188-beta
  • Win32Metadata version (if explicitly set by project):
  • Target Framework: net7.0
  • LangVersion (if explicitly set by project): 11
@jnm2 jnm2 added the bug Something isn't working label Feb 18, 2023
@AArnott
Copy link
Member

AArnott commented Feb 22, 2023

This is by design. COM interfaces must not derive from IDispatch, but instead use the [InterfaceType(ComInterfaceType.InterfaceIsIDispatch)] attribute instead. So there is no correct use of IDispatch as a direct interface (that I know of).

If marshaling is turned off, the structs generated include the members of IDispatch directly in them (as required), so in that case too, there is no need to generate IDispatch.

@AArnott
Copy link
Member

AArnott commented Feb 22, 2023

We do have a means to communicate certain banned APIs so that attempts to generate them produce a warning or error. I'll add something for these special interfaces.

@AArnott
Copy link
Member

AArnott commented Feb 22, 2023

Looking at #862 it appears you only need it for its guid. We can probably solve that another way. Perhaps by emitting an IID_IDispatch constant or something.

@smourier
Copy link

smourier commented Jun 3, 2024

I'm working with more recent version of .NET Core, and there's nothing implicit about IDispatch anymore. Only IUnknown is really useless (apart for its IID).

Also, even with .NET Framework, it's not because it can implement it that we shouldn't be allowed to use it, like in interop scenarios talking to an unmanaged object itself implementing IDispatch.

Can you alllow CsWin32 to generate it? Or at maybe add a possiblity to tweak this in NativeMethods.json?

@AArnott
Copy link
Member

AArnott commented Jun 3, 2024

@smourier: In .NET Framework, one either works with COM objects in a marshaled or unmarshaled scenario. When working with marshaling, IDispatch would be toxic and confusing because .NET Framework handles it automatically. When using the unmarshaled mode (which is indeed accessible through NativeMethods.json), CsWin32 does generate an IDispatch type for you when needed.

@smourier
Copy link

smourier commented Jun 3, 2024

@smourier: In .NET Framework, one either works with COM objects in a marshaled or unmarshaled scenario. When working with marshaling, IDispatch would be toxic and confusing because .NET Framework handles it automatically. When using the unmarshaled mode (which is indeed accessible through NativeMethods.json), CsWin32 does generate an IDispatch type for you when needed.

I must be missing something but when I put IDispatch in NativeMethod.txt I get this:

warning PInvoke003: This API will not be generated. This COM interface is implicit in the runtime. Interfaces that derive from it should apply the [InterfaceType(ComInterfaceType.InterfaceIsIDispatch)] attribute instead.

@AArnott
Copy link
Member

AArnott commented Jun 3, 2024

You can't request it. It isn't generated directly. In marshaled mode it's an attribute. In non-marshaled mode, its members are included in the structs that act as your RCW/CCW.

@smourier
Copy link

smourier commented Jun 3, 2024

You can't request it. It isn't generated directly. In marshaled mode it's an attribute. In non-marshaled mode, its members are included in the structs that act as your RCW/CCW.

I just need the IDispatch interface generated because I need it to call an unmanaged object or also to implement IDispatch in a non standard way. I've done that before, defined IDispatch manually and it worked fine, so I guess I will just do the same. I've a hard time to understand CsWin32 behavior here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants