释放 OleVariant 后面的接口的正确方法是什么?
我正在尝试找到一种安全/确定性的方法来释放封装在 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
我想将 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;
这个解决方案安全吗还是有我忽略的更好的解决方案?
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?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
编译器显然使用隐式本地接口变量作为 CreateOleObject 的返回值。然后在例程结束时释放它,这对你来说太晚了。
有几种方法可以解决这个问题。首先,您可以明确由
CreateOleObject
返回的IDispatch
接口引用。这使您可以控制其生命周期。另一种方法是将调用
CreateOleObject
的代码移至具有自己作用域的单独例程中。由于隐式本地引用位于
DoWork
范围内,因此它会在DoWork
结束时释放,因此在运行CoUninitialize
之前释放。我的建议是使用第二个选项,它更干净,并强制编译器代表您完成工作。
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 byCreateOleObject
. This allows you to control its lifetime.An alternative would be to move the code that called
CreateOleObject
into a separate routine with its own scope.Since the implicit local reference is within the scope of
DoWork
it is released at the end ofDoWork
and 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.