http://d.puremagic.com/issues/show_bug.cgi?id=4092
Summary: broken memory management for COM objects derived from IUnknown Product: D Version: unspecified Platform: Other OS/Version: Windows Status: NEW Severity: normal Priority: P2 Component: druntime AssignedTo: s...@invisibleduck.org ReportedBy: r.sagita...@gmx.de --- Comment #0 from Rainer Schuetze <r.sagita...@gmx.de> 2010-04-14 23:44:39 PDT --- Currently, instances of classes that derive from IUnknown are allocated from the C-heap (see lifetime.d, function _d_newclass), but are never released in the default implementation ComObject (see std.c.windows.com, ComObject.Release()), because invariants might still be called. In addition, ComObjects are not known to the garbage collector (which is completely useless in at least 99% of all cases), so you have to override ComObject's new to avoid a bad collection while executing the class constructor. I suggest allocating ComObjects from standard garbage collected objects, and let the default imlpementation add ranges to the GC when AddRef is called with reference count 0, and removing the range when Release is called: class ComObject : IUnknown { // [... QueryInterface ...] override ULONG AddRef() { LONG lRef = InterlockedIncrement(&count); if(lRef == 1) { uint sz = this.classinfo.init.length; GC.addRange(cast(void*) this, sz); } return lRef; } override ULONG Release() { LONG lRef = InterlockedDecrement(&count); if (lRef == 0) { GC.removeRange(cast(void*) this); } return cast(ULONG)lRef; } } Otherwise, the garbage collector is responsible of releasing memory. This also lets ComObject be handled like normal objects in D-Code (no need to call AddRef/Release). Here's the patch to lifetime.d: Index: lifetime.d =================================================================== --- lifetime.d (revision 282) +++ lifetime.d (working copy) @@ -98,7 +98,7 @@ void* p; debug(PRINTF) printf("_d_newclass(ci = %p, %s)\n", ci, cast(char *)ci.name); - if (ci.m_flags & 1) // if COM object + if (0 & ci.m_flags & 1) // if COM object { /* COM objects are not garbage collected, they are reference counted * using AddRef() and Release(). They get free'd by C's free() * function called by Release() when Release()'s reference count goes -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------