[fpc-devel] Reference counting interface objects
Adriaan van Os
fpc at microbizz.nl
Thu Oct 16 15:02:55 CEST 2014
Jonas Maebe wrote:
>
> On 16 Oct 2014, at 12:35, Adriaan van Os wrote:
>
>> Now, it seems (correct me if I am wrong) that theEvent doesn't need to
>> be manually released, because it has been declared as an OUT parameter
>> rather than a VAR parameter. So, if this is true, this information is
>> crucial when writing interface bindings.
>
> Nothing ever needs to be manually released, regardless of whether it's a
> VAR or OUT parameter. That's the whole point of automatic reference
> counting)
I agree for pure Pascal code, where a parameter can be OUT or VAR and automatic release will work
in both cases. However, I disagree for interfacing with external interfaces. It must be clear for
the bindings-writer that VAR in the bindings instead of (what should have been) OUT can cause a
memory leak. This is tricky enough that it deserves an explanation in the manual. For example, I
think (from Windows MediaFoundation)
type
IMFMediaEventGenerator = interface( IUnknown) ...
....
function GetEvent( dwFlags: DWORD; OUT ppEvent: IMFMediaEvent): HResult; stdcall;
is correct, whereas
function GetEvent( dwFlags: DWORD; VAR ppEvent: IMFMediaEvent): HResult; stdcall;
will leak memory.
>
> Regarding the effects of the various qualifiers:
> * nothing (value): the reference count of the parameter is increased (I
> forgot whether it's the caller or callee that does it) on entry and
> decreased on exit
> * OUT: the reference count of the value that's passed in is decreased by
> 1, and the variable that's passed into the procedure is initialized to
> "empty" (nil, but that's an implementation detail)
> * VAR: nothing happens to the reference count. A reference to the
> original variable is passed in, and changing it or reading it has
> exactly the same effect as changing/reading the original variable.
> * CONST: this is the only tricky one. Again nothing happens to the
> reference count, but because you can pass non-lvalues here. In
> particular, you can pass a class implementing an interface rather than
> the interface itself, which can cause the class to be freed
> unexpectedly. See the example at
> http://docwiki.embarcadero.com/RADStudio/XE7/en/Using_Reference_Counting .
> The same can happen with functions returning a class instance passed to
> a function expecting a CONST interface parameter. There is an open bug
> report about adding a warning for it:
> http://bugs.freepascal.org/view.php?id=19503
Thanks for the explanation. This clarifies things.
Regards,
Adriaan van Os
More information about the fpc-devel
mailing list