为什么在调用AviFileExit()之前需要调用IAviFile指针?

问题描述:

我发现一个堆栈溢出后用样本显示如何得到一个AVI文件的时间:为什么在调用AviFileExit()之前需要调用IAviFile指针?

Getting AVI file duration

我修改了它为我的目的,我的Delphi 6应用程序,并创建下面的代码。最初我在调用AviFileExit()之前删除了核心IAviFile指针的那一行。但是当我这样做时,当AviFileExit()被调用时,我得到了访问冲突。我恢复了这一行,访问冲突消失了。

为什么在调用AviFileExit()之前需要调用IAviFile引用?这是内存泄漏吗?我会认为正常的接口引用计数在这里可以正常工作,但显然它不会。是否有另一种方法来消除像调用AviStreamRelease()或类似的错误?

这里是我的代码:

function getAviDurationSecs(theAviFilename: string): Extended; 
var 
    aviFileInfo : TAVIFILEINFOW; 
    intfAviFile : IAVIFILE; 
    framesPerSecond : Extended; 
begin 
    intfAviFile := nil; 

    AVIFileInit; 

    try 
     // Open the AVI file. 
     if AVIFileOpen(intfAviFile, PChar(theAviFilename), OF_READ, nil) <> AVIERR_OK then 
      raise Exception.Create('(getAviDurationSecs) Error opening the AVI file: ' + theAviFilename); 

     try 
      // Get the AVI file information. 
      if AVIFileInfoW(intfAviFile, aviFileInfo, sizeof(aviFileInfo)) <> AVIERR_OK then 
       raise Exception.Create('(getAviDurationSecs) Unable to get file information record from the AVI file: ' + theAviFilename); 

      // Zero divide protection. 
      if aviFileInfo.dwScale < 1 then 
       raise Exception.Create('(getAviDurationSecs) Invalid dwScale value found in the AVI file information record: ' + theAviFilename); 

      // Calculate the frames per second. 
      framesPerSecond := aviFileInfo.dwRate/aviFileInfo.dwScale; 

      Result := aviFileInfo.dwLength/framesPerSecond; 
     finally 
      AVIFileRelease(intfAviFile); 
      // Commenting out the line below that nukes the IAviFile 
      // interface reference leads to an access violation when 
      // AVIFileExit() is called. 
      Pointer(intfAviFile) := nil; 
     end; 
    finally 
     AVIFileExit; 
    end; 
end; 

您必须手动清除您的变量,因为德尔福不知道AVIFileRelease()发布的接口。 AVIFileRelease()不会将变量设置为nil,因此该变量仍然具有非零值。如果你没有手动清除它,Delphi将尝试在变量超出范围时调用Release()调用AVIFileExit())并崩溃。

IAVIFile接口是IUknown后代,所以我不知道为什么微软首先创建了AVIFileRelease()功能。它递减接口的引用计数并在计数降到零时执行清理。接口背后的实现可以简单地在内部处理,而不需要显式函数。所以这是微软的坏处。

+0

谢谢雷米。至少我现在知道为什么。 –