Thread overview | |||||
---|---|---|---|---|---|
|
April 04, 2023 [Issue 23819] defining your own interface IUnknown messes up vtable without any warning | ||||
---|---|---|---|---|
| ||||
https://issues.dlang.org/show_bug.cgi?id=23819 --- Comment #1 from Felix Hufnagel <puremagic@zoadian.de> --- To add to that, my initial problem was, that when using two mixins, somehow the order i mix them in is important. but shouldn't the vtable automatically be correct when i inherit an interface? in my mixin IMPLEMENT_REFCOUNT; and mixin QUERY_INTERFACE!(FUnknown, IMessage); will generate the wrong vtable, unless swapped. extern (C++) class HostMessage : IMessage { public: // somehow the order of the two mixins matters mixin IMPLEMENT_REFCOUNT; mixin QUERY_INTERFACE!(FUnknown, IMessage); } mixin template IMPLEMENT_REFCOUNT() { override uint addRef() { return 1; } override uint release() { return 1; } } mixin template QUERY_INTERFACE(Interfaces...) { override tresult queryInterface (ref const TUID _iid, void** obj) { return 1; } } interface IMessage : FUnknown { public: nothrow: // @nogc: /** Returns the message ID (for example "TextMessage"). */ FIDString getMessageID(); /** Sets a message ID (for example "TextMessage"). */ void setMessageID(FIDString id /*in*/); /** Returns the attribute list associated to the message. */ IAttributeList getAttributes(); __gshared immutable TUID iid = INLINE_UID(0x936F033B, 0xC6C047DB, 0xBB0882F8, 0x13C1E613); } interface FUnknown : IUnknown { __gshared immutable TUID iid = INLINE_UID(0x00000000, 0x00000000, 0xC0000000, 0x00000046); } interface IUnknown { tresult queryInterface(ref const(TUID) _iid, void** obj); uint addRef(); uint release(); } -- |
March 20 [Issue 23819] defining your own interface IUnknown messes up vtable without any warning | ||||
---|---|---|---|---|
| ||||
https://issues.dlang.org/show_bug.cgi?id=23819 Richard Cattermole <alphaglosined@gmail.com> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |alphaglosined@gmail.com --- Comment #2 from Richard Cattermole <alphaglosined@gmail.com> --- Changing the calling convention to extern(Windows) and conversion to being a C++ interface is a documented behavior of the interface IUnknown (and in line with the definition provided by the Windows API). https://dlang.org/spec/interface.html#com-interfaces https://dlang.org/spec/abi.html#interfaces As for not warning you, it would if you marked your class Test method with override. This appears to be a requirement in general for classes and is not COM-specific. ``` onlineapp.d(2): Error: function `extern (C) void onlineapp.Test.test()` does not override any function, did you mean to override `extern (Windows) void onlineapp.IUnknown.test()`? onlineapp.d(1): Error: class `onlineapp.Test` interface function `extern (Windows) void test()` is not implemented ``` As for the mixin templates orders, the order in the vtable shouldn't be the same order as defined in IUnknown. When you cast your object to IUnknown then it'll line up, but for all other children, it won't. -- |
March 20 [Issue 23819] defining your own interface IUnknown messes up vtable without any warning | ||||
---|---|---|---|---|
| ||||
https://issues.dlang.org/show_bug.cgi?id=23819 --- Comment #3 from Felix Hufnagel <puremagic@zoadian.de> --- "A COM interface is defined as one that derives from the interface core.sys.winÂdows.com.IUnknown. A COM interface differs from a regular D interface in that: It derives from the interface core.sys.windows.com.IUnknown." I never derived from core.sys.windows.com.IUnknown. I just named my own interface IUnknown, and the compiler did some magic. if I don't define it, it even says it's undefined. -- |
Copyright © 1999-2021 by the D Language Foundation