06.01.2015 Views

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

SHOW MORE
SHOW LESS

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

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!