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(){
InterfacePtrparent(this, UseDefaultIID());
if( parent ) {
InterfacePtrparentPanel(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(){
InterfacePtrparent(this, UseDefaultIID());
if( parent ) {
InterfacePtrparentPanel(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:
Post a Comment