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