Bug 12607 – Document that IUnknown classes must mark toString with extern(D) when overriding it
Status
RESOLVED
Resolution
FIXED
Severity
normal
Priority
P1
Component
dlang.org
Product
D
Version
D2
Platform
All
OS
Windows
Creation time
2014-04-21T14:40:00Z
Last change time
2014-04-21T22:16:27Z
Assigned to
andrej.mitrovich
Creator
andrej.mitrovich
Comments
Comment #0 by andrej.mitrovich — 2014-04-21T14:40:36Z
Test 1:
-----
import core.sys.windows.windows;
import std.c.windows.com;
class C : IUnknown
{
string toString() { return "E"; }
extern(Windows) HRESULT QueryInterface(const(IID)*, void**) { return typeof(return).init; }
extern(Windows) uint AddRef() { return 0; }
extern(Windows) uint Release() { return 0; }
}
void main() { }
-----
$ dmd test.d
> Deprecation: class test.C use of object.Object.toString() hidden by C is deprecated. Use 'alias Object.toString toString;' to introduce base class overload set.
Test 2:
-----
import core.sys.windows.windows;
import std.c.windows.com;
class C : IUnknown
{
override string toString() { return "E"; }
extern(Windows) HRESULT QueryInterface(const(IID)*, void**) { return typeof(return).init; }
extern(Windows) uint AddRef() { return 0; }
extern(Windows) uint Release() { return 0; }
}
void main() { }
-----
$ dmd test.d
> Error: function test.C.toString does not override any function, did you mean to override 'object.Object.toString'?
Comment #1 by schveiguy — 2014-04-21T14:49:10Z
I JUST was playing around with this.
I think an IUnknown class is implicitly extern(Windows) for all the methods. You have to explicitly mark toString as extern(D).
Comment #2 by andrej.mitrovich — 2014-04-21T14:52:46Z
(In reply to Steven Schveighoffer from comment #1)
> I JUST was playing around with this.
>
> I think an IUnknown class is implicitly extern(Windows) for all the methods.
Ah, thanks. I kept seeing people use "extern(Windows):" in their COM classes and thought that was strange.
I'll update this so it becomes a documentation issue.
Comment #3 by andrej.mitrovich — 2014-04-21T14:57:51Z
The only problem is, how do you call toString via an IUnknown interface? I need it to implement better support for formatting COM objects, see Issue 11175.
IUnknown doesn't declare toString, but if you cast an IUnknown interface to object you get back null.
Comment #4 by schveiguy — 2014-04-21T15:03:51Z
(In reply to Andrej Mitrovic from comment #3)
> The only problem is, how do you call toString via an IUnknown interface?
You can't. Because the layout of IUnknown interfaces MUST follow COM, the RTTI link to D's typeinfo system is missing. Remember that a proper D interface has a mechanism of defining how to find the object start (and therefore the vtable). An IUnknown interface does not have that.
Note that an IUnknown object may not even be a D object!
Once you go into IUnknown land, there's no coming back out (bwahahaha!)
Comment #5 by andrej.mitrovich — 2014-04-21T15:12:14Z
(In reply to Steven Schveighoffer from comment #4)
> Once you go into IUnknown land, there's no coming back out (bwahahaha!)
And somewhat ironically the spec defines IUnknown as using the extern(System) calling convention, rather than saying it's extern(Windows), as if non-Windows systems will ever support COM.
Comment #6 by github-bugzilla — 2014-04-21T22:16:27Z