Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/delphi/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
.net Delphi中COM对象的销毁_.net_Delphi_Com - Fatal编程技术网

.net Delphi中COM对象的销毁

.net Delphi中COM对象的销毁,.net,delphi,com,.net,Delphi,Com,使用一些.net程序集,通过COM在delphi中调用它 var intf: ITest; ... intf:= CreateComObject(CLASS_TEST) as ITest; ... //here comes some stuff ... 我必须做些什么来破坏它以释放内存。是否?您最好用 intf := nil; 当你不再需要它的时候。最好使用try…finally intf:=nil

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

var
   intf: ITest;

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

我必须做些什么来破坏它以释放内存。是否?

您最好用

       intf := nil;
当你不再需要它的时候。最好使用
try…finally intf:=nilintf
被定义为
fIntf
,即作为类属性,则在
Destroy
重写方法中


如果在堆栈上定义了
intf
,我们将在方法末尾自动释放它。有一个隐藏的
try…finally intf:=nil;结束编译器生成的
块以释放
intf
实例。

COM对象是引用计数的,当引用计数达到零时,它们会自动销毁。每当代码添加或删除对象引用时,编译器将自动添加对
\u AddRef
\u Release
接口方法的调用。将引用COM对象的变量设置为
nil
将调用
\u Release
(减少引用计数),如果引用计数为零,对象也将被释放(如果引用计数不为零,则不会释放)。当一个变量超出范围时(即当程序退出时为局部变量),如果该变量引用COM对象(或任何引用计数的Delphi接口),编译器也将调用
\u Release

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

所有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对象时,您都有责任调用
\u AddRef
。每次放弃对COM对象的引用时,您都会被约定调用
\u Release

\u AddRef
\u Release
的规范实现是为了实现对象维护一个引用计数变量,该变量随着引用的获取和释放而递增和递减。如果对
\u Release
的调用将此引用计数设置为0,则对象将销毁自身

接口的Delphi实现代表您管理对
\u AddRef
\u Release
的调用。当您分配给接口变量时,编译器将发出以下代码:

  • 在变量先前引用的接口上调用
    \u Release
    ,如果它确实先前引用了某些内容
  • 在变量现在引用的接口上调用
    \u AddRef
编译器还安排在变量离开作用域时调用
\u Release

这意味着您不需要采取任何特殊措施来确保COM对象被销毁。当对象的最后一个引用离开作用域时,它们自然会被销毁


但是,如果确实希望提前销毁对象,则只需将
nil
赋值给保存接口的变量即可。请注意,这当然是假定没有其他引用保存到该接口。

我不熟悉delphi。你们所说的“在堆栈上定义”是什么意思,每个变量都在var部分定义,所以它们都在堆栈上?是的,它在堆栈中。因此,Delphi将在方法末尾发布此引用。如果intf存储在对象字段中,它将在对象销毁期间释放它。当我说“释放”时,我并不坚持引用的对象将被销毁,它的行为取决于它是如何设计的。p、 另外,当您想要更快地释放对象时,即如果您想要控制释放顺序,则需要为接口引用分配nil,-1,因为您“应该”释放内存不是真的。这是完全可选的。@Fred我写了“应该”,因为我发现,例如,一些Delphi编译器(不是旧的,我说的是Delphi 2010),即使它们“应该”并且有文档记录这样做。。。因此,我不能100%肯定情况会一直如此。我很高兴,如果你是如此自信,没有这样的问题发生过的接口。当然,我知道
对象
已被弃用,接口也不是…;)