Jonas Maebe wrote:

No, it won't:
1) if the external code expects it to be "out" and you declare it as "var": the caller will decrease the reference count and the ppEvent that you get will have as initial value "nil". You can just assign to it like normal. 2) if the external code expects it to be "var" and you declare it as "out": the caller will not do anything and hence the ppEvent will not be nil. However, assignments to the "out" parameter still cause its reference count to be decreased. After all, you can assign multiple times to an "out" parameter, so the compiler cannot assume it's already nil. The only problem that could happen here is if you would explicitly write your code in a way that behaves differently depending on whether the initial value is nil (e.g., assigning something to it only in one branch of an if-statement, and then later checking whether it's "still" nil to determine whether you have to assign something else to it).

Sorry, but the above explanation flabberghasts me.

case 1.

MF binding declaration

         function GetEvent
            (     dwFlags                   : DWORD;
              out ppEvent                   : IMFMediaEvent): HResult; stdcall;

Pascal code is the caller and Windows MF is the callee.

        theResult                     := theSession.GetEvent
          ( 0, theEvent);

 The compiler sees the out parameter and (as you explained)

* 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)

This produces the following assembly

# [195] theResult                     := theSession.GetEvent
        leal    -24(%ebp),%eax
        call    FPC_INTF_DECR_REF
        leal    -24(%ebp),%eax
        pushl   %eax
        pushl   $0
        pushl   -8(%ebp)
        movl    -8(%ebp),%edx
        testl   %edx,%edx
        jne     .Lj260
        movl    $210,%eax
        call    FPC_HANDLEERROR
.Lj260:
        movl    (%edx),%eax
        call    *12(%eax)
        movl    %eax,-16(%ebp)

where FPC_INTF_DECR_REF is found in rtl/inc/objpas.inc

    procedure fpc_intf_decr_ref(var i: pointer);[public,alias: 
'FPC_INTF_DECR_REF']; compilerproc;
      begin
        if assigned(i) then
          begin
            IUnknown(i)._Release;
            i:=nil;
          end;
      end;

So, before Windows returns a new value for ppEvent, the compiler emits a call to _Release, preventing a memory leak for our Pascal theEvent parameter.

case 2.

MF binding declaration

         function GetEvent
            (     dwFlags                   : DWORD;
              var ppEvent                   : IMFMediaEvent): HResult; stdcall;

Pascal code is the caller and Windows MF is the callee.

        theResult                     := theSession.GetEvent
          ( 0, theEvent);

The compiler sees the out parameter and (as you explained)

* 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.

This produces the following assembly

# [195] theResult                     := theSession.GetEvent
        leal    -24(%ebp),%eax
        pushl   %eax
        pushl   $0
        pushl   -8(%ebp)
        movl    -8(%ebp),%edx
        testl   %edx,%edx
        jne     .Lj260
        movl    $210,%eax
        call    FPC_HANDLEERROR

So, Windows returns a new value for ppEvent, the compiler does not emit a call to _Release, and our Pascal theEvent parameter leaks (except if you assume that Windows MF behaves different for both cases, i.c. if NIL is passed or not. This is highly unlikely, because the declaration in Mfobjects.idl is

    HRESULT GetEvent(
        [in] DWORD dwFlags,
        [out] IMFMediaEvent** ppEvent
        );

which ignores the input value 
<http://msdn.microsoft.com/en-us/library/hh916383.aspx>.

Regards,

Adriaan van Os

_______________________________________________
fpc-devel maillist  -  [email protected]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel

Reply via email to