Introduction to EON SDK - Construction IT research at VTT
Introduction to EON SDK - Construction IT research at VTT
Introduction to EON SDK - Construction IT research at VTT
Create successful ePaper yourself
Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.
User Guide<br />
Techniques<br />
Techniques<br />
Smart pointers<br />
All COM objects encapsul<strong>at</strong>e an integer value th<strong>at</strong> keeps track of<br />
object usage. Each time a client cre<strong>at</strong>es a COM object the AddRef<br />
function of th<strong>at</strong> object is called. This increment the object’s<br />
reference counter by one and prevents the destruction of th<strong>at</strong> object<br />
when it goes out of scope. This way separ<strong>at</strong>e parts of the client or<br />
even different clients may use the same object th<strong>at</strong> will persist as<br />
long as its reference counter is larger than zero. When an object’s<br />
Release function is called its reference counter is decrement by one,<br />
if this result in a zero value the object deletes it self.<br />
Each time a new pointer is introduced AddRef should be called,<br />
otherwise the pointer may become invalid. And before the pointer goes<br />
out of scope the programmer has <strong>to</strong> call Release otherwise there will<br />
be a memory leak. Trouble occurs when a programmer has several<br />
pointers <strong>to</strong> several different COM objects, e.g.:<br />
#include <br />
#include "shlobj.h" // Shell COM components<br />
#include "objbase.h"<br />
int main(void)<br />
{<br />
HRESULT hr = CoInitialize(NULL);<br />
if (FAILED(hr))<br />
{<br />
CoUninitialize();<br />
return -1;<br />
}<br />
IUnknown* pUnk1;<br />
// CoCre<strong>at</strong>eInstance calls AddRef<br />
hr = CoCre<strong>at</strong>eInstance<br />
(<br />
CLSID_ShellLink,<br />
NULL,<br />
CLSCTX_INPROC_SERVER,<br />
IID_IUnknown,<br />
(void **) &pUnk1<br />
);<br />
if (FAILED(hr))<br />
{<br />
CoUninitialize();<br />
return -1;<br />
}<br />
IUnknown* pUnk2 = pUnk1;<br />
ULONG lRef = pUnk2->AddRef();<br />
printf("Reference counter = %d\n", lRef);<br />
lRef = pUnk2->Release();<br />
printf("Reference counter = %d\n", lRef);<br />
lRef = pUnk1->Release();<br />
printf("Reference counter = %d\n", lRef);<br />
}<br />
CoUninitialize();<br />
return 0;<br />
Obviously it is quite easy <strong>to</strong> forget ether AddRef and Release on pUnk2<br />
or Release on pUnk1 since CoCre<strong>at</strong>eInstance did AddRef for us. To avoid<br />
this behavior we could encapsul<strong>at</strong>e all COM pointers in a templ<strong>at</strong>e<br />
class th<strong>at</strong> calls AddRef when it is assigned <strong>to</strong> an object and Release<br />
30<br />
<strong>EON</strong> <strong>SDK</strong> 2.53.0