首页 文章

在Delphi中销毁COM对象

提问于
浏览
7

有一些.net程序集,通过COM在delphi中调用它 .

var
   intf: ITest;

...
   intf:= CreateComObject(CLASS_TEST) as ITest;
   ...
   //here comes some stuff
   ...

我必须做些什么来破坏它以释放记忆 . 或不?

4 回答

  • 2

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

  • 12

    你应该更好地释放内存

    intf := nil;
    

    当你不再需要它时 . 如果 intf 被定义为 fIntf ,则更好地使用 try...finally intf := nil; 块或 Destroy 覆盖方法,即作为类属性 .

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

  • 6

    COM对象是引用计数的,当引用计数达到零时它们会自动销毁 . 只要您的代码添加对对象的引用或将其删除,编译器就会自动添加对 _AddRef_Release 接口方法的调用 . 将引用COM对象的变量设置为 nil 将调用 _Release (递减引用计数),如果引用计数达到零,则对象也将被释放(如果引用计数不为零则不会) . 当变量超出范围(即局部变量,当过程退出时)时,如果变量引用COM对象(或任何引用计数的Delphi接口),编译器也将调用 _Release .

  • 6

    该对象自动释放 . 但是,如果您明确要释放 intf 变量所持有的引用,则可以将其设置为nil .

相关问题