I am confused. I want to use the function PathToPidlBind
from Jedi JCL and I see that they don't release the IShellFolder interfece reurned by SHGetDesktopFolder
after using it. Microsoft docs says: "The calling application is responsible for eventually freeing the interface by calling its IUnknown::Release method.". I tried to use DesktopFolder._Release
but I get access violation. I'm not sure this is what Microsoft refers to. So how this shold be done right ?
From Jedi JCL:
function PathToPidlBind(const FileName:String; out Folder:IShellFolder): PItemIdList;
var
Attr, Eaten: ULONG;
PathIdList: PItemIdList;
DesktopFolder: IShellFolder;
Path, ItemName: PWideChar;
begin
Result:=nil;
Path:=PWideChar(ExtractFilePath(FileName));
ItemName:=PWideChar(ExtractFileName(FileName));
if Succeeded(SHGetDesktopFolder(DesktopFolder)) then begin
Attr:=0;
if Succeeded(DesktopFolder.ParseDisplayName(0, nil, Path, Eaten, PathIdList, Attr)) then begin
if Succeeded(DesktopFolder.BindToObject(PathIdList, nil, IID_IShellFolder, Pointer(Folder))) then begin
if Failed(Folder.ParseDisplayName(0, nil, ItemName, Eaten, Result, Attr)) then begin
Folder:=nil;
Result:=DriveToPidlBind(FileName, Folder);
end;
end;
PidlFree(PathIdList);
end
else Result:=DriveToPidlBind(FileName, Folder);
end;
end;
COM interfaces are reference counted, and the Delphi compiler generates code to automatically manage the reference counting for you. Each time an interface variable is assigned,
Release
is called if the variable is not nil, andAddRef
is called if the new value is not nil. When the variable goes out of scope,Release
is called if not nil.So it is a mistake to manually release the way you did. You released the interface manually, and then the compiler tried to release it automatically. You have to let the compiler do the work.
If you do wish to release an interface before it goes out of scope, assign
nil
to it:But there is no need for you to do that in this example.
The Delphi designers don't want you to explicitly call
AddRef
andRelease
, so they named then_AddRef
and_Release
in order to discourage you from calling these methods directly.