在Delphi中销毁COM对象

Jac*_*ich 7 .net delphi com

有一些.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接口),编译器也将调用.


Arn*_*hez 6

你应该更好地释放内存

       intf := nil;
Run Code Online (Sandbox Code Playgroud)

当你不再需要它时.使用try...finally intf := nil;块更好,或者在Destroyoverride方法intf中定义为fIntf,即作为类属性.

如果intf在堆栈上定义,它将在方法结束时自动释放.try...finally intf := nil; end编译器生成一个隐藏块以释放intf实例.


Dav*_*nan 6

所有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保存接口的变量即可.请注意,这当然是假设没有其他引用持有该接口.