开发者

Destroying COM object in Delphi

Have some .ne开发者_StackOverflowt assembly, calling it in delphi through COM.

var
   intf: ITest;

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

Must i do something to destruct it to free memory. Or not?


COM objects are reference-counted, and they get automatically destroyed when the reference count reaches zero. The compiler will automatically add calls to _AddRef and _Release interface methods whenever your code adds a reference to the object or removes it. Setting a variable referencing a COM object to nil will call _Release (decrementing the reference count), and if the reference count reaches zero the object is also freed (it won't be if the reference count is not zero). When a variable goes out of scope (i.e. a local variable, when the procedure exits), the compiler will also call _Release if the variable references a COM object (or any reference-counted Delphi interface).


All COM interfaces must implement IUnknown:

IUnknown = interface
  function QueryInterface(const IID: TGUID; out Obj): HResult; stdcall;
  function _AddRef: Integer; stdcall;
  function _Release: Integer; stdcall;
end;

IUnknown provides two services. First of all, QueryInterface allows for clients to obtain the other interfaces that the object may implement. The second service is that of lifetime management.

Every time you take a reference to a COM object it is your responsibility to call _AddRef. Every time you give up a reference to a COM object, you are contracted to call _Release.

The canonical implementation of _AddRef and _Release is for the implementing object to maintain a reference count variable which is incremented and decremented as references are taken and released. If a call to _Release sets this reference count to 0 then the object destroys itself.

The Delphi implementation of interfaces manages the calls to _AddRef and _Release on your behalf. When you assign to an interface variable the compiler emits code that:

  • Calls _Release on the interface that the variable previously referred to, if indeed it did previously refer to something.
  • Calls _AddRef on the interface that the variable now refers to.

The compiler also arranges for _Release to be called whenever the variable leaves scope.

What this means is that you need to take no special action whatsoever to ensure that your COM objects will be destroyed. They will naturally be destroyed when the last reference to the object leaves scope.

If however, you do wish to destroy an object ahead of time, then you simply assign nil to the variable holding the interface. Note that this is of course presuming that no other references are held to that interface.


You should better release the memory with

       intf := nil;

When you don't need it any more. Better with a try...finally intf := nil; block, or in the Destroy overriden method if intf is defined as fIntf, i.e. as a class property.

If intf is defined on stack, it will we freed automatically at the end of the method. There is an hidden try...finally intf := nil; end block generated by the compiler to free the intf instance.


The object is released automatically. However, if you explicitly want to release the reference that the intf variable holds, you can set it to nil.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜