digitalmars.D.learn - toHash() and Interfaces
- Nrgyzer (30/30) May 05 2011 Hey guys,
- Steven Schveighoffer (9/38) May 06 2011 (cast(Object)b).toHash()
- Nrgyzer (7/54) May 06 2011 'toHash'
- Stewart Gordon (11/15) May 11 2011 Firstly, IUnknown is defined in the Phobos files, not a language built-i...
- Steven Schveighoffer (37/57) May 16 2011 No, the compiler treats it specially, COM interfaces and classes have a ...
Hey guys, I'm trying to call toHash() in a class which receives an interface class as input param. But I always get "Error: no property 'toHash' for type...". My code looks like: module iFBlock; private { import std.stream; } interface IFBlock { public { void write(Stream); } } module myFile; private { import iFBlock; } class MyFile { private { IFBlock[hash_t] pBlocks; } public { void addBlock(IFBlock b) { pBlocks[b.toHash()] = b; } } } Is there any chance to get the hash of the FBlock-interface? Thanks in advance!
May 05 2011
On Thu, 05 May 2011 17:03:51 -0400, Nrgyzer <nrgyzer gmail.com> wrote:Hey guys, I'm trying to call toHash() in a class which receives an interface class as input param. But I always get "Error: no property 'toHash' for type...". My code looks like: module iFBlock; private { import std.stream; } interface IFBlock { public { void write(Stream); } } module myFile; private { import iFBlock; } class MyFile { private { IFBlock[hash_t] pBlocks; } public { void addBlock(IFBlock b) { pBlocks[b.toHash()] = b; } } } Is there any chance to get the hash of the FBlock-interface?(cast(Object)b).toHash() D has this horrible notion that any interface can be for a COM object, even though COM interfaces can only inherit from IUnknown (known statically). Therefore, interfaces that don't inherit from IUnknown are not considered Objects, even though they could and should be. So you have to manually cast an interface to Object in order to call an Object function. -Steve
May 06 2011
== Auszug aus Steven Schveighoffer (schveiguy yahoo.com)'s ArtikelOn Thu, 05 May 2011 17:03:51 -0400, Nrgyzer <nrgyzer gmail.com>wrote:'toHash'Hey guys, I'm trying to call toHash() in a class which receives an interface class as input param. But I always get "Error: no propertyobject,for type...". My code looks like: module iFBlock; private { import std.stream; } interface IFBlock { public { void write(Stream); } } module myFile; private { import iFBlock; } class MyFile { private { IFBlock[hash_t] pBlocks; } public { void addBlock(IFBlock b) { pBlocks[b.toHash()] = b; } } } Is there any chance to get the hash of the FBlock-interface?(cast(Object)b).toHash() D has this horrible notion that any interface can be for a COMeven though COM interfaces can only inherit from IUnknown (known statically). Therefore, interfaces that don't inherit fromIUnknown arenot considered Objects, even though they could and should be. So you have to manually cast an interface to Object in order tocall anObject function. -SteveAh, okay - a bit dirty solution, but it works, thanks!
May 06 2011
On 06/05/2011 13:02, Steven Schveighoffer wrote: <snip>D has this horrible notion that any interface can be for a COM object, even though COM interfaces can only inherit from IUnknown (known statically). Therefore, interfaces that don't inherit from IUnknown are not considered Objects, even though they could and should be.Firstly, IUnknown is defined in the Phobos files, not a language built-in. There might be multiple IUnknowns, defined in different modules (e.g. because some set of bindings has its own copy). How should the compiler identify the IUnknown to use? By name? By the signatures of functions specified within it? By fully qualified name? Secondly, I guess it's perfectly possible for some other system, besides COM, to create non-D objects that implement D interfaces.So you have to manually cast an interface to Object in order to call an Object function.Which you can do, if you are certain that the object will always be a D object. I guess the whole point is to protect you from those cases where you can't be sure. Stewart.
May 11 2011
On Wed, 11 May 2011 19:43:03 -0400, Stewart Gordon <smjg_1998 yahoo.com> wrote:On 06/05/2011 13:02, Steven Schveighoffer wrote: <snip>No, the compiler treats it specially, COM interfaces and classes have a different layout than D objects, so the compiler has to generate different code if the class implements an interface which inherits from std.c.windows.com.IUnknown. From the spec: A COM interface is defined as one that derives from the interface std.c.windows.com.IUnknown. A COM interface differs from a regular D interface in that: * It derives from the interface std.c.windows.com.IUnknown. * It cannot be the argument of a DeleteExpression. * References cannot be upcast to the enclosing class object, nor can they be downcast to a derived interface. To accomplish this, an appropriate QueryInterface() would have to be implemented for that interface in standard COM fashion. * Classes derived from COM interfaces are COM classes. * The default linkage for member functions of COM classes is extern(System). * The first member of the vtbl[] is not the pointer to the InterfaceInfo, but the first virtual function pointer. ---------------- There is nothing here that makes it seem like this is undetectable at compile time. IMO: * cast(Object)someComInterface => compiler error * Object o = someComInterface => compiler error * Object o = someNormalInterface => success Is all doable without incurring any problems.D has this horrible notion that any interface can be for a COM object, even though COM interfaces can only inherit from IUnknown (known statically). Therefore, interfaces that don't inherit from IUnknown are not considered Objects, even though they could and should be.Firstly, IUnknown is defined in the Phobos files, not a language built-in. There might be multiple IUnknowns, defined in different modules (e.g. because some set of bindings has its own copy). How should the compiler identify the IUnknown to use? By name? By the signatures of functions specified within it? By fully qualified name?Secondly, I guess it's perfectly possible for some other system, besides COM, to create non-D objects that implement D interfaces.But none of these exist today. All cases of 'alternative' interfaces have alternative layouts and statically detectable triggers (such as IUnknown) that would allow us to statically allow or disallow implicit casting to Object. If we simply make a rule right now that alternative layouts have to be typed with some modifier (like extern(C++) for example) we can have implicit casting to object and get rid of all these ridiculous problems.The compiler can always be sure, it just isn't programmed to know it yet... -SteveSo you have to manually cast an interface to Object in order to call an Object function.Which you can do, if you are certain that the object will always be a D object. I guess the whole point is to protect you from those cases where you can't be sure.
May 16 2011