当前位置: 代码迷 >> 综合 >> 于COM计数器 (AddRef()和Release())的问题
  详细解决方案

于COM计数器 (AddRef()和Release())的问题

热度:33   发布时间:2024-01-16 03:09:53.0

  问题内容:关于COM计数器 (AddRef()和Release())的问题。 我在一个函数中获取一个com的接口指针(Item),并将它返回。如下:我在外面对这个函数进行调用时,我写下下面两种代码,都可以通过,为什么?

  • 原讨论链接:http://community.csdn.net/expert/topicview1.asp?id=801615
  • 所属论坛:ATL/ActiveX/COM     审核组:VC/MFC
  • 提问者:COM_MOC     解决者:wistaria
  • 感谢:joke100
  • 关键字:VC/MFC 函数 调用 控件 字段 触发器 变量 语句 堆栈 窗体 ATL/ActiveX/COM COM基础 正则
  • 答案:

    调用函数:
    ItemType* fnGetItem()
    {
           ...

           ItemType* Item = NULL;
           if( !SUCCEEDED( hr = GetItem(&Item) ) )
           {//COM内部计数器自动加1,是吧?
               AfxMessageBox("Error");
           }

           return Item;
    }

    代码片段1:
        ....

        ItemType* Item1 = NULL;
        
        Item1 = fnGetItem();
        Item1->AddRef();
        ....
        
        Item1->Release();
     


    代码片段2:
        ....

        ItemType* Item1 = NULL;
        
        Item1 = fnGetItem();
        //Item1->AddRef();不要这行语句程序也能运行。
        ....
        
        Item1->Release();






    wistaria Answer:

    每当 QueryInterface 为一个对象分配一个新指针时,QueryInterface 有责任在返回该指针前调用 AddRef。这就是为什么不必为得到的指针调用 AddRef。
    (注意,CoCreateInstance 调用 QueryInterface,而 QueryInterface 调用 AddRef,所以对象的第一个接口指针也是这样。)

    如果您复制了一个接口指针,则需要调用 AddRef,这样该接口的引用计数才准确。

    joke100 Answer:

    首先你自己要注意addref和release的配对使用,尤其是自己写的时候,当调用其他代码时,要知道别人的代码是否已经调过addref了,一定要保证你的工程里使用同一套规范。

    象前面的例子比较简单,因为fnGetItem内部已经addref,所以外部要多一次release.

    第一种写法会导致Item1总在内存中不被释放,直到整个程序退出,由系统来释放,

    第二种才是正确的。

  相关解决方案