Jen*_*off 8 delphi com finalization delphi-2007
我试图找到一种安全/确定的方法来释放封装在OleVariant中的接口.
AFAICS Delphi在程序结束时发布接口引用,但在我的情况下我必须提前完成,因为我必须关闭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
Run Code Online (Sandbox Code Playgroud)
我把OleVariant放在一个额外的类实例中,我可以在调用之前释放它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;
Run Code Online (Sandbox Code Playgroud)
这个解决方案是安全的还是我忽略了一个更好的解决方案?
编译器显然使用隐式本地接口变量作为返回值CreateOleObject
.然后在例程结束时释放,对你来说太迟了.
有几种方法可以打败这个.首先,您可以明确IDispatch
指出返回的接口引用CreateOleObject
.这允许您控制其寿命.
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;
Run Code Online (Sandbox Code Playgroud)
另一种方法是将调用的代码移动CreateOleObject
到具有自己范围的单独例程中.
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;
Run Code Online (Sandbox Code Playgroud)
由于隐式本地引用在其范围内,DoWork
因此它在结束时释放,DoWork
因此在运行之前释放CoUninitialize
.
我的建议是使用更清晰的第二个选项,并强制编译器代表您完成工作.
归档时间: |
|
查看次数: |
2667 次 |
最近记录: |