core.sys.windows.com.ComObject apparently has wrongly laid out Vtable

Carl Sturtivant sturtivant at gmail.com
Wed Mar 20 14:26:24 UTC 2024


Here's the test of that extern(C++) ComObject.
```D
import std.stdio;
import com = core.sys.windows.com;
import windows = core.sys.windows.windows;

import comdef;

pragma(lib,"onecore");

void main() {
     //auto COMobject = new com.ComObject();
     auto COMobject = new ComObject();
     IUnknown* ip = cast(IUnknown*)COMobject;
     writeln(COMobject.count);
     writeln("       ip vtable: ", ip.lpVtbl);
     auto vtable = COMobject.__vptr;
     writeln("COMobject vtable: ", vtable);
     writeln("ip &AddRef: ", &ip.lpVtbl.AddRef);
     writeln("ip offset: ", cast(void*)&ip.lpVtbl.AddRef - 
cast(void*)ip.lpVtbl);
     auto ipaddref = cast(void*)ip.lpVtbl.AddRef;
     writeln("       ip AddRef: ", ipaddref);
     auto addref = cast(void*)(&COMobject.AddRef).funcptr;
     writeln("COMobject AddRef: ", addref);
     writeln("COMobject AddRef : ip AddRef offset: ", addref - 
ipaddref);
     COMobject.AddRef();
     writeln(COMobject.count);
     ip.lpVtbl.AddRef(ip);
     writeln(COMobject.count);
}
```
Note that I cast COMobject (which is a new ComObject) directly to 
a IUnknown*. (Here IUnknown is the struct defined in `comdef.c` 
just the way Windows defines it.) This code works! The result:
```
0
        ip vtable: 7FF6AFEB0360
COMobject vtable: 7FF6AFEB0360
ip &AddRef: 7FF6AFEB0368
ip offset: 8
        ip AddRef: 7FF6AFE31580
COMobject AddRef: 7FF6AFE31580
COMobject AddRef : ip AddRef offset: 0
1
2
```
This shows that the Vtable of the extern(C++) ComObject has COM 
interface layout. However, if I remove `extern(C++)` from the 
definition of the new ComObject class, now this does NOT work. 
Result without extern(C++) is:
```
0
        ip vtable: 7FF6C74D02B0
COMobject vtable: 7FF6C74D02B0
ip &AddRef: 7FF6C74D02B8
ip offset: 8
        ip AddRef: 7FF6C74619E0
COMobject AddRef: 7FF6C7451580
COMobject AddRef : ip AddRef offset: -66656
1
1
```
This shows the Vtable of the ComObject does not have COM 
interface layout.


More information about the Digitalmars-d mailing list