为什么在调用AviFileExit()之前必须清除IAviFile指针?

3
我发现了一个Stack Overflow的帖子,其中包含一个示例,展示如何获取AVI文件的持续时间: 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;
1个回答

5
您需要手动清除变量,因为Delphi不知道AVIFileRelease()释放了接口。 AVIFileRelease()不会为您将变量设置为nil,因此变量仍具有非nil值。如果您不手动清除它,则Delphi将在其作用域之外(即在AVIFileExit()调用后)尝试调用变量上的Release()并崩溃。 IAVIFile接口是IUknown的后代,因此我不知道Microsoft为什么首先创建了AVIFileRelease()函数。它将减少接口的引用计数,并在计数降至零时执行清理。实现接口背后的实现可以简单地在内部处理而无需显式功能。所以这是Microsoft的错。

谢谢Remy。至少我现在知道为什么了。 - Robert Oschler

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接