Re: Wrapping a C lib and reference counting
On May 28, 3:00 pm, Mosfet <mos...@anonymous.org> wrote:
Hi,
I would like to wrapp a C library I wrote used to access address book on
windows mobile and basically here is how it is designed :
typedef void GDAddrBook;
typedef void GDAbItem;
GYNOID_API ErrorCode
GDAddrBook_Open(OsHandle osParam, GDAddrBook** gppAddrbook);
GYNOID_API ErrorCode
GDAddrBook_Close(GDAddrBook* gpAddrbook);
GYNOID_API ErrorCode
GDAddrBook_GetCount(GDAddrBook* gpAddrbook, int* ulCount);
GYNOID_API ErrorCode
GDAbItem_Release(GDAbItem* gpContact);
GYNOID_API ErrorCode
GDAddrBook_GetItem(GDAddrBook* gpAddrbook, int iIndex, GDAbItem**
gppAbItem);
GYNOID_API void*
GDAbItem_GetProperty(GDAbItem* gpContact, EAbItemProp eContactProp);
So A typical use to get the first addrbook item would be (simple case
with no error checking):
GDCTSTR lpFirstName;
GDAddrBook* gdAb;
GDAbItem* gdAbItem;
GDAddrBook_Open(0, &gdAb);
GDAddrBook_GetItem(gdAb, 0, &gdAbItem);
lpFirstName = (GDCTSTR) GDAbItem_GetProperty(gdAbItem, eAbFirstName);
// Now we release our two "objects"
GDAbItem_Release(gdAbItem);
GDAddrBook_Release(gdAb)
Now I would like to provide a C++ wrapper where C++ objects would hold
GDxxxx pointers and would call Gdxxxx_Release automatically
AddrBook ab;
AddrBookItem abItem;
abItem = ab.getItem(0);
GDString = abItem.getProperty(eAbFirstName);
The problem is about
AddrBookItem AddrBook::getItem(int iIndex)
{
GDAbItem* gpAbItem = NULL;
GDAddrBook_GetItem(m_gpAb, iIndex, &gpAbItem);
AddrBookItem abItem(gpAbItem);
return abItem;
}
Because If I write something like that, my local abItem will be
destroyed and will call its destructor, so my internal pointer will be
released.
The only way I can see is to use reference counting but is it the only wa=
y ?
You could also duplicate it at each copy.
For your function, you can also create an artefact AddrBookItemRef
that destroy its ressource if it was not used by a AddrBookItem.
class AddrBookItem
{
//...
class AddrBookItemRef
{
public:
AddrBookItemRef(GDAbItem*p=NULL):ptr(p){}
AddrBookItemRef(const AddrBookItemRef& r):ptr(p.release()){}
~AddrBookItemRef(){if(ptr)GDAbItem_Release(ptr);}
private:
GDAbItem* release()const{GDAbItem*p=ptr;ptr=NULL;return p;}
mutable GDAbItem* ptr;
};
AddrBookItem(const AddrBookItemRef& r)
{
internal=r.release();
}
//...
};
You would have to decide what to do with copy operator for
AddrBookItemRef (I would say forbid it).
If you want to allow it, you can directly return a
std::auto_ptr<GDAbItem>.
You could also use garbage collection :)
Another approach would be to use reference like that :
ab.getItem(0, abItem );
but what is the best way and how to solve my issues ?
Duplicating your data doesn't seem a big deal unless you can find
another persistence root.
--
Michael