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,
Releaseis called if the variable is not nil, andAddRefis called if the new value is not nil. When the variable goes out of scope,Releaseis 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
nilto it:But there is no need for you to do that in this example.
The Delphi designers don't want you to explicitly call
AddRefandRelease, so they named then_AddRefand_Releasein order to discourage you from calling these methods directly.