I am trying to find a safe/deterministic way to release an interface which is encapsulated in an OleVariant.
AFAICS Delphi releases interface references at the end of a procedure, but in my case I have to do it earlier, because I have to shut down COM.
procedure Test;
var
LLibrary: OleVariant;
begin
CoInitialize(nil);
try
LLibrary := Null;
try
LLibrary := CreateOleObject(LibraryName);
finally
LLibrary := Unassigned; // <-- I would like to release the interface here
end;
finally
CoUninitialize; // <-- Shutdown of COM
end;
end; // <-- The compiler releases the interface here
I though of putting the OleVariant in an extra class instance that I can free before I call CoUninitialize.
procedure Test;
var
Container: TLibraryContainer; // Holds the OleVariant
begin
CoInitialize(nil);
try
Container := TLibraryContainer.Create;
try
{...}
finally
Container.Free;
end;
finally
CoUninitialize;
end;
end;
Is this solution safe or is there a better solution I have overlooked?
The compiler is clearly using an implicit local interface variable for the return value from
CreateOleObject. This is then released at the end of the routine, too late for you.There are a couple of ways to defeat this. First of all you could be explicit about the
IDispatchinterface reference returned byCreateOleObject. This allows you to control its lifetime.An alternative would be to move the code that called
CreateOleObjectinto a separate routine with its own scope.Since the implicit local reference is within the scope of
DoWorkit is released at the end ofDoWorkand therefore before you runCoUninitialize.My recommendation is to use the second option which is cleaner and forces the compiler to do the work on your behalf.