www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - what keeps a COM object alive?

reply "finalpatch" <fengli gmail.com> writes:
A typical COM server would create a new object (derived from 
IUnknown), return it to the caller (potentially written in other 
languages). Because the object pointer now resides outside of D's 
managed heap, does that mean the object will be destroyed when 
the GC runs? A normal COM object written in C++ relies on 
reference counting to manage its life cycle but in D the ref 
counting seems not serving any purpose. The AddRef()/Release() of 
std.c.windows.com.ComObject maintains a ref count, but doesn't 
really use it for any thing. There's a comment in Release() says 
"let the GC reap it", but how does the GC know the object is okay 
to destroy?
Jun 11 2013
parent reply Sean Cavanaugh <WorksOnMyMachine gmail.com> writes:
On 6/11/2013 10:38 PM, finalpatch wrote:
 A typical COM server would create a new object (derived from IUnknown),
 return it to the caller (potentially written in other languages).
 Because the object pointer now resides outside of D's managed heap, does
 that mean the object will be destroyed when the GC runs? A normal COM
 object written in C++ relies on reference counting to manage its life
 cycle but in D the ref counting seems not serving any purpose. The
 AddRef()/Release() of std.c.windows.com.ComObject maintains a ref count,
 but doesn't really use it for any thing. There's a comment in Release()
 says "let the GC reap it", but how does the GC know the object is okay
 to destroy?
COM is by definition ref counted. In D you generally need to store a COM pointer in a struct and maintain the refcount with that struct (increment on copy, decrement in destructor, etc). Its not too hard, as 'alias this' usage can wrap the pointer's methods easily enough.
Jun 12 2013
parent reply finalpatch <fengli gmail.com> writes:
Hi Sean,

Thanks for your reply. I have no problem with client side COM
programming in D. What I'm asking is if I write a COM object in D (in
this case the D code is a COM server), then it looks like I have to
store a reference to that COM object in some globally reachable place
(eg. add it to a global array, so that it won't be destroyed by the GC
while the C++/.NET client is still using it), and then manually remove
that reference when the object's ref count drops to zero for the GC to
collect it.

This feels even more cumbersome than in C++ because in C++ we can simply
delete this in the Release() method, there's no need to store a
reference in a global place.

Sean Cavanaugh <WorksOnMyMachine gmail.com> writes:
 COM is by definition ref counted.  In D you generally need to store a
 COM pointer in a struct and maintain the refcount with that struct
 (increment on copy, decrement in destructor, etc).  Its not too hard,
 as 'alias this' usage can wrap the pointer's methods easily enough.
-- finalpatch
Jun 12 2013
parent reply "Richard Webb" <webby beardmouse.org.uk> writes:
On Wednesday, 12 June 2013 at 14:41:05 UTC, finalpatch wrote:

 This feels even more cumbersome than in C++ because in C++ we 
 can simply
 delete this in the Release() method, there's no need to store a
 reference in a global place.
Juno does this by allocating the object on the non-gc heap, adding it as a GC root, and then deleting it when the refcount reaches 0. It works ok, though I think the current implementation has some issues.
Jun 12 2013
parent reply finalpatch <fengli gmail.com> writes:
"Richard Webb" <webby beardmouse.org.uk> writes:

 On Wednesday, 12 June 2013 at 14:41:05 UTC, finalpatch wrote:

 This feels even more cumbersome than in C++ because in C++ we can
 simply
 delete this in the Release() method, there's no need to store a
 reference in a global place.
Juno does this by allocating the object on the non-gc heap, adding it as a GC root, and then deleting it when the refcount reaches 0. It works ok, though I think the current implementation has some issues.
I was reading the CHello sample that ships with DMD. I don't see anything that can prevent the GC from killing a running object, this makes me wonder whether it is actually a correct sample. -- finalpatch
Jun 12 2013
parent "Richard Webb" <webby beardmouse.org.uk> writes:
I was referring to the COM server support stuff in the Juno 
library, which allocates COM objects outside the GC heap so the 
GC will never collect them.

See 
https://github.com/JesseKPhillips/Juno-Windows-Class-Library/blob/master/j
no/com/core.d#L3147 
for an example.
Jun 12 2013