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 IDispatch
interface reference returned by CreateOleObject
. This allows you to control its lifetime.
procedure Test;
var
intf: IDispatch;
LLibrary: OleVariant;
begin
CoInitialize(nil);
try
intf := CreateOleObject(LibraryName);
try
LLibrary := intf;
finally
VarClear(LLibrary);
intf := nil;
end;
finally
CoUninitialize;
end;
end;
An alternative would be to move the code that called CreateOleObject
into a separate routine with its own scope.
procedure DoWork;
var
LLibrary: OleVariant;
begin
LLibrary := CreateOleObject(LibraryName);
//do stuff with LLibrary
end;
procedure Test;
begin
CoInitialize(nil);
try
DoWork;
finally
CoUninitialize;
end;
end;
Since the implicit local reference is within the scope of DoWork
it is released at the end of DoWork
and therefore before you run CoUninitialize
.
My recommendation is to use the second option which is cleaner and forces the compiler to do the work on your behalf.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With