有一些.net程序集,通过COM在delphi中调用它。
var
intf: ITest;
...
intf:= CreateComObject(CLASS_TEST) as ITest;
...
//here comes some stuff
...
我必须做些什么来破坏它以释放记忆。或者不是?
答案 0 :(得分:12)
COM对象是引用计数的,当引用计数达到零时它们会自动销毁。只要您的代码添加对对象的引用或将其删除,编译器就会自动添加对_AddRef
和_Release
接口方法的调用。将引用COM对象的变量设置为nil
将调用_Release
(递减引用计数),如果引用计数达到零,则对象也将被释放(如果引用则不会被引用)数不是零)。当变量超出范围(即局部变量,当过程退出时)时,如果变量引用COM对象(或任何引用计数的Delphi接口),编译器也将调用_Release
。
答案 1 :(得分:6)
你最好用
释放内存 intf := nil;
当你不再需要它时。最好使用try...finally intf := nil;
块,或Destroy
覆盖方法,如果intf
定义为fIntf
,即作为类属性。
如果在堆栈上定义了intf
,它将在方法结束时自动释放。编译器生成了一个隐藏的try...finally intf := nil; end
块来释放intf
实例。
答案 2 :(得分:6)
所有COM接口都必须实现IUnknown
:
IUnknown = interface
function QueryInterface(const IID: TGUID; out Obj): HResult; stdcall;
function _AddRef: Integer; stdcall;
function _Release: Integer; stdcall;
end;
IUnknown
提供两项服务。首先,QueryInterface
允许客户端获取对象可能实现的其他接口。第二项服务是终身管理。
每次引用COM对象时,您都有责任致电_AddRef
。每次您放弃对COM对象的引用时,您都会签约以致电_Release
。
_AddRef
和_Release
的规范实现是为了实现对象来维护引用计数变量,该变量在获取和释放引用时递增和递减。如果对_Release
的调用将此引用计数设置为0,则该对象会自行销毁。
Delphi的接口实现代表您管理对_AddRef
和_Release
的调用。分配给接口变量时,编译器会发出以下代码:
_Release
,如果它之前确实引用了某些内容。_AddRef
。编译器还安排在变量离开范围时调用_Release
。
这意味着您不需要采取任何特殊操作来确保您的COM对象将被销毁。当对象的最后一次引用离开范围时,它们自然会被销毁。
但是,如果您希望提前销毁对象,则只需将nil
分配给保存接口的变量。请注意,这当然是假设没有其他引用持有该接口。
答案 3 :(得分:2)
对象自动释放。但是,如果您明确要释放intf
变量所持有的引用,则可以将其设置为nil。