www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Wrong vtable for COM interfaces that don't inherit IUnknown

reply KytoDragon <kytodragon e.mail.de> writes:
I am currently trying to write a XAudio2 backend and have come 
across the problem, that some of the interfaces for XAudio2's COM 
objects seem to be missing the first entry in their vtable. After 
reading the iterface article in the spec 
(https://dlang.org/spec/interface.html#com-interfaces) it seems 
that only interfaces inheriting from 
core.stdc.windows.com.IUnknown (or any interface named 
"IUnknown") get the COM interface layout instead of the D layout.

What can I do to get the COM layout on interfaces that don't 
inherit IUnknown?
Examples: IXAudio2Voice or any of the IXAudio2*Callback 
interfaces. I have already declared everything extern(Windows), 
but that does not fix it.
Jul 15 2019
next sibling parent Nicholas Wilson <iamthewilsonator hotmail.com> writes:
On Monday, 15 July 2019 at 22:01:25 UTC, KytoDragon wrote:
 I am currently trying to write a XAudio2 backend and have come 
 across the problem, that some of the interfaces for XAudio2's 
 COM objects seem to be missing the first entry in their vtable. 
 After reading the iterface article in the spec 
 (https://dlang.org/spec/interface.html#com-interfaces) it seems 
 that only interfaces inheriting from 
 core.stdc.windows.com.IUnknown (or any interface named 
 "IUnknown") get the COM interface layout instead of the D 
 layout.

 What can I do to get the COM layout on interfaces that don't 
 inherit IUnknown?
 Examples: IXAudio2Voice or any of the IXAudio2*Callback 
 interfaces. I have already declared everything extern(Windows), 
 but that does not fix it.
From memory COM interfaces are really just `extern(C++) interface`s, so extern(C++) interface IXAudio2Voice { //methods... } should do the trick
Jul 15 2019
prev sibling parent reply evilrat <evilrat666 gmail.com> writes:
On Monday, 15 July 2019 at 22:01:25 UTC, KytoDragon wrote:
 I am currently trying to write a XAudio2 backend and have come 
 across the problem, that some of the interfaces for XAudio2's 
 COM objects seem to be missing the first entry in their vtable. 
 After reading the iterface article in the spec 
 (https://dlang.org/spec/interface.html#com-interfaces) it seems 
 that only interfaces inheriting from 
 core.stdc.windows.com.IUnknown (or any interface named 
 "IUnknown") get the COM interface layout instead of the D 
 layout.

 What can I do to get the COM layout on interfaces that don't 
 inherit IUnknown?
 Examples: IXAudio2Voice or any of the IXAudio2*Callback 
 interfaces. I have already declared everything extern(Windows), 
 but that does not fix it.
As you can see it is by design. IUnknown has different vtbl[] comparing to regular D classes/interfaces. If it works with declaring your own empty IUnknown use it, also you can try extern(C++) which does similar thing to vtable, it might even work! Another option is to craft your own "vtable" with structs, but I'm not going into details about that, you can always google how to do it in C and adapt. And finally you can swap vtable for object instances at runtime, this however is the most complicated and error prone solution, I for example doesn't fully understand D rules for vtable constructing, esp. confusing is that interface entry notice, so anything non trivial (such as class inheriting from class w/multiple interfaces) is beyond me. Expect heavy AV storm. Also from what I see MS done this intentionally, means they either no longer loves COM or there was some other good reason. Oh and let me put this here... Have you seen this? It even has very simple xaudio example. https://code.dlang.org/packages/directx-d
Jul 15 2019
next sibling parent KytoDragon <kytodragon e.mail.de> writes:
On Tuesday, 16 July 2019 at 01:38:49 UTC, evilrat wrote:
 As you can see it is by design. IUnknown has different vtbl[] 
 comparing to regular D classes/interfaces. If it works with 
 declaring your own empty IUnknown use it, also you can try 
 extern(C++) which does similar thing to vtable, it might even 
 work!
...
 Oh and let me put this here...
 Have you seen this? It even has very simple xaudio example.
 https://code.dlang.org/packages/directx-d
Yes, i found that after posting. Declaring your interface extern(C++) and the methods in the interface extern(Windows) seems to do the trick. I hoped there would be a more elegant solution than to annotate each interface, but oh well. Thanks anyway!
Jul 16 2019
prev sibling parent reply Kagamin <spam here.lot> writes:
On Tuesday, 16 July 2019 at 01:38:49 UTC, evilrat wrote:
 Also from what I see MS done this intentionally, means they 
 either no longer loves COM or there was some other good reason.
Primary consumer of COM interfaces is Visual Basic. It was really only Bill Gates who loved Basic, he wrote a Basic interpreter in 1975 and created Microsoft as a business that sold Basic interpreters. As gamedev was locked in C++, there was no real use case for COM there, so MS probably does the expected thing and goes with straight C++.
Jul 20 2019
parent reply rikki cattermole <rikki cattermole.co.nz> writes:
On 21/07/2019 5:44 PM, Kagamin wrote:
 On Tuesday, 16 July 2019 at 01:38:49 UTC, evilrat wrote:
 Also from what I see MS done this intentionally, means they either no 
 longer loves COM or there was some other good reason.
Primary consumer of COM interfaces is Visual Basic. It was really only Bill Gates who loved Basic, he wrote a Basic interpreter in 1975 and created Microsoft as a business that sold Basic interpreters. As gamedev was locked in C++, there was no real use case for COM there, so MS probably does the expected thing and goes with straight C++.
I suspect both of you are wrong in this regard. "No other XAudio2 objects are reference-counted; their lifetimes are explicitly controlled using create and destroy calls, and are bounded by the lifetime of the XAudio2 object that owns them." https://docs.microsoft.com/en-us/windows/win32/api/xaudio2/nn-xaudio2-ixaudio2 COM is used heavily in WinAPI since about Vista. Pretty much all new functionality has been exposed by it and NOT extern(Windows) functions which was the standard during up to about XP (for example notification icons would today be COM based but isn't). E.g. jump lists https://docs.microsoft.com/en-us/windows/win32/api/shobjidl_core/nn-shobjidl_core-icustomdestinationlist Windows isn't the only one with a solution like COM. Linux has D-Bus which underpins most newer Desktop Environments. You can do everything from shutdown, log out and even send notification messages via it.
Jul 21 2019
parent Kagamin <spam here.lot> writes:
On Sunday, 21 July 2019 at 07:04:00 UTC, rikki cattermole wrote:
 COM is used heavily in WinAPI since about Vista. Pretty much 
 all new functionality has been exposed by it and NOT 
 extern(Windows) functions which was the standard during up to 
 about XP (for example notification icons would today be COM 
 based but isn't).

 E.g. jump lists 
 https://docs.microsoft.com/en-us/windows/win32/api/shobjidl_core/nn-shobjidl_core-icustomdestinationlist
Shell object library? It shipped with Internet Explorer 4 and was installable on windows 95. Shell (explorer) is not really winapi, it's more or less a normal userland application that provides integration, like an RPC server, in this way it can be similar to d-bus, but it's difficult to say, because the library abstracts whether it works in process or out of process, most (older) shell objects work in process and simply provide shell logic like moving files to trash bin and creating shortcuts.
Jul 21 2019