Note that there are some explanatory texts on larger screens.

plurals
  1. POHow can I maintain a weak reference on a COM object in C++?
    primarykey
    data
    text
    <p>In my application, I'm hooking various functions for creating COM objects (such as <a href="http://msdn.microsoft.com/en-us/library/ms686615(v=vs.85).aspx" rel="noreferrer"><code>CoCreateInstanceEx</code></a>) to get notified whenever some object is created. I'm keeping track of all created objects in a <a href="http://www.cplusplus.com/reference/stl/list/" rel="noreferrer"><code>std::list</code></a> and I'm iterating over that list to do various things (like checking which OLE objects have been activated).</p> <p>The issue with this is that right now, whenever adding an <a href="http://msdn.microsoft.com/en-us/library/ms680509(v=vs.85).aspx" rel="noreferrer"><code>IUnknown</code></a> pointer to my list, I call <a href="http://msdn.microsoft.com/en-us/library/ms691379(v=vs.85).aspx" rel="noreferrer"><code>IUnknown::AddRef</code></a> on it to make sure that it doesn't get destroyed while I'm tracking it. That's not what I really want though; the lifetime of the object should be as long (or short) as it is without my tracing code, so I'd rather like to maintain a <a href="http://en.wikipedia.org/wiki/Weak_reference" rel="noreferrer">weak reference</a> on the objects. Whenever the last reference to some tracked COM object is removed (and thus the object gets destroyed), I'd like to get notified so that I can update my bookkeeping (e.g. by setting the pointer in my list to <code>NULL</code>).*</p> <p>What's the best way to do this? Right now, I'm patching the (first) VTable of all created objects so that the calls to <a href="http://msdn.microsoft.com/en-us/library/ms682317(v=vs.85).aspx" rel="noreferrer"><code>IUnknown::Release</code></a> via the first vtable get notified. However, this won't work for COM interfaces which inherit from multiple interfaces (and thus have multiple vtables), but I'm not sure whether this is really a problem: given the <a href="http://msdn.microsoft.com/en-us/library/ms686590%28v=vs.85%29.aspx" rel="noreferrer">Rules for Implementing QueryInterface</a>, there should always be just one <code>IUnknown</code> returned by <a href="http://msdn.microsoft.com/en-us/library/ms682521(v=vs.85).aspx" rel="noreferrer"><code>IUnknown::QueryInterface</code></a>, right? So I could do that and then patch that vtable.</p> <p>Furthermore, this approach is also a bit hairy since it involves creating thunks which generate some code. I only implemented this for 32bit so far. Not a big issue, but still.</p> <p>I'm really wondering whether there isn't a more elegant way to have a weak reference to a COM object. Does anybody know?</p> <p>*: The next thing I'll have to solve is making this work correctly in case I have active iterators (I'm using custom iterator objects) traversing the list of COM objects. I may need to keep track of the active iterators and once the last one finished, remove all null pointers from the list. Or something like that.</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload