Wednesday, May 26, 2004

InDesign newbiee problems

I was having an interface leak with InDesign, such leak caused all sort of others leaks that they had the potential to drive me to look at others places, fortunately I've got quite a lot experience with COM interface leaks.

After all the suspecting function was this one:

IPMUnknown* getPanelView(){

InterfacePtr parent(this, UseDefaultIID());
if( parent ) {
InterfacePtr parentPanel(parent->GetParent(), UseDefaultIID());
if( parentPanel )
return parentPanel->QueryParentFor(IID_ICONTROLVIEW);
}
return nil;
} // getPanelView

In particular I was using such function with an InterfacePtr like this:

InterfacePtr<IControlView> panel(getPanelView(), UseDefaultIID());

However if you look at the include file for IWidgetParent, you will find that QueryParentFor will return a reference incremented ptr to interface this means I will leak a reference to that interface. InterfacePtr have a constructor that doesn't call AddRef on the interface and it's the one that didn't do the QueryInterface. So the correct InterfacePtr is:

InterfacePtr<IControlView> panel(getPanelView());

But getPanelView must return an IControlView* or we should cast it here, I prefer the first solution, so I'll have:

IControlView* getPanelView(){

InterfacePtr parent(this, UseDefaultIID());
if( parent ) {
InterfacePtr parentPanel(parent->GetParent(), UseDefaultIID());
if( parentPanel )
return static_cast<IControlView*>(parentPanel->QueryParentFor(IID_ICONTROLVIEW));
}
return nil;
} // getPanelView

Moral of the story: read carefully documentation *and* include files before using any complex sdk.

No comments: