[Lazarus] IUnknown and reference counting

Sven Barth pascaldragon at googlemail.com
Thu Mar 21 14:10:49 CET 2013


Am 21.03.2013 13:55, schrieb Kostas Michalopoulos:
> I haven't used (COM) interfaces so far since i didn't found any use 
> for them in my code, but i didn't knew about their reference counting 
> properties. That could save a lot of headaches i have with my 3D world 
> editor's lightmap generation (currently there is some wrong memory 
> deallocation somewhere that crashes the editor in partial lightmap 
> recalculations). I plan to redesign it at some point soon and i was 
> thinking how to handle this. Since there is native refcounting support 
> in FPC it makes things much easier.
>
> However i did a small test and i noticed something that, to me (as 
> someone who hasn't used COM at all) looks a bit weird:
>
> If i do a declaration like
>
> type
>   IResource = interface  end;
>   TResource = class(TInterfacedObject, IResource) ... stuff ... end;
>
>   TSomething = class
>     ...
>     Resources: array of TResource;
>     ...
>   end;
>
> then reference counting doesn't work. However if i change Resources to
>
>     Resources: array of IResource;
>
> then it works. It seems that the compiler checks only the "topmost" 
> type and doesn't check if TResource implements the IResource and thus 
> doesn't do any reference counting. Is this a bug or it is supposed to 
> work this way?
>
> If the latter, is there a way to make the compiler do reference 
> counting on a variable that has a class type which implements an 
> interface instead of a type that is an interface itself? Or is there 
> any other form of reference counted classes?
>
The compiler does not check for any topmost type. It uses reference 
counting only for variables that are of an interface type not for a 
class type.

E.g.:

=== example begin ===

var
   i: IInterface;
   t: TInterfacedObject;
begin
   t := TInterfacedObject.Create;
   t.Free;
   // no reference counting is done here

   i := TInterfacedObject.Create;
   i := Nil;
   // reference counting is done here
end;

=== example end ===

Regards,
Sven




More information about the Lazarus mailing list