www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - COM objects

When newing a class derived from IUnknown, the compiler recognises it as a 
COM object and calls std.c.stdlib.malloc instead of allocating from the GC. 
It also skips registering a finalizer, so the destructor never gets called 
on COM objects. Yet I see nothing that frees that memory, so COM objects 
must be leaking all over the show.

In C++, one might go about it like this (actually a smart pointer would be 
preferable):

class COMObject : public IUnknown {
    LONG ref_;
public:
    COMObject() : ref_(0) {
        AddRef();
    }
    ULONG __stdcall AddRef() {
        return InterlockedIncrement(&ref_);
    }
    ULONG __stdcall Release() {
        LONG rc = InterlockedDecrement(&ref_);
        if (rc == 0) {
            delete this;
            return 0;
        }
        return ref_;
    }
    HRESULT __stdcall QueryInterface(REFIID riid, void** ppvObject) {
        // QI stuff omitted
        if (*ppvObject != 0)
            AddRef();
        return S_OK;
    }
};

COMObject* obj = new COMObject;
obj->Release();

The D version should be much the same, but calling delete has no effect on 
non-GC resources. Calling std.c.stdlib.free when the ref count gets to zero 
would appear to be the solution, but I've found that to cause access 
violations in a lot of cases.

Has anyone figured out a reliable way to do this? 
Oct 05 2006