2012-05-18 102 views
3

我發現一個堆棧溢出後用樣本顯示如何得到一個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; 

回答

5

您必須手動清除您的變量,因爲德爾福不知道AVIFileRelease()發佈的接口。 AVIFileRelease()不會將變量設置爲nil,因此該變量仍然具有非零值。如果你沒有手動清除它,Delphi將嘗試在變量超出範圍時調用Release()調用AVIFileExit())並崩潰。

IAVIFile接口是IUknown後代,所以我不知道爲什麼微軟首先創建了AVIFileRelease()功能。它遞減接口的引用計數並在計數降到零時執行清理。接口背後的實現可以簡單地在內部處理,而不需要顯式函數。所以這是微軟的壞處。

+0

謝謝雷米。至少我現在知道爲什麼。 –

相關問題