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