none
OOM AddRef()/Release() in Outlook 2013 COM Add-in RRS feed

  • Question

  • I am a developer of Outlook COM Add-in. The add-in works well in Outlook 2010 but it crashes in Outlook 2013. After debugging the code, it crashes when assign the pointer to NULL after releasing an OOM object. Here is the sample code:

                   

    TestExplorer::TestExplorer(_ExplorerPtr pExplorer)
    {
        if(pExplorer)
        {
            m_pExplorer = pExplorer;
            m_pExplorer->AddRef();
        }
    }

    TestExplorer::~TestExplorer()
    {
        if(m_pExplorer)
        {
           m_pExplorer->Release();
           m_pExplorer = NULL;
        }
    }

    HRESULT TestExplorer::SelectionChange()
    {
            SelectionPtr pSelection = NULL;
            IDispatchPtr pIDispatch = NULL;             

            try
            {
                pSelection = m_pExplorer->GetSelection();
                if (pSelection)
                {
                    long lCount = pSelection->GetCount();
                    for( long index = 1; index <= lCount && bContinue; index++)
                    {
                        pIDispatch = pSelection->Item(index);

                        if (pIDispatch)
                        {
                            .......

                            pIDispatch->Release();
                            pIDispatch = NULL;
                        }
                    }
                }
            }
            catch (...)
            {
            }

            if (pSelection)
            {
                pSelection->Release();
                pSelection = NULL;
            }

            if (pIDispatch)
            {
                pIDispatch->Release();
                pIDispatch = NULL;
            }

        return S_OK;
    }

    What is wrong in the code? Why does it work in Outlook 2010 but not Outlook 2013? Should the pointer not be released?

    Tuesday, November 13, 2012 7:55 PM

Answers

  • I understand that this is C++.

    By get() I was refering to std:auto_ptr<>.get() method which returns the underlying pointer to the COM object. You are not using raw COM pointers, you are using smart pointers.

    Once again, if you are using smart pointers, there is no reason to explicilty call AddRef/Release.

    If you prefer fine control over the reference counting, do not use smart pointers.

    Did you actually step into the line m_pExplorer = pExplorer?

    The answer to all of your other questions is yes.


    Dmitry Streblechenko (MVP)
    http://www.dimastr.com/redemption
    Redemption - what the Outlook
    Object Model should have been
    Version 5.4 is now available!

    Wednesday, November 14, 2012 6:27 PM

All replies

  • If you are using smart pointers, there is no reason to Add/Release.

    Setting a smart pointer to NULL will automatically call Release. Assigning a value to a smart pointer will automatically AddRef it.

    I suspect that the line

    m_pExplorer = pExplorer;

    does not AddRef the object since you are assigning a smart pointer to a smart pointer. Try to change that line to

    m_pExplorer = pExplorer.get();


    Dmitry Streblechenko (MVP)
    http://www.dimastr.com/redemption
    Redemption - what the Outlook
    Object Model should have been
    Version 5.4 is now available!

    Tuesday, November 13, 2012 8:13 PM
  • This is C++ code. There is no get() function for OOM Explorer object. pExplorer pointer comes from Application::ActiveExplorer() function. m_pExplorer = pExplorer adds the reference count to 1,  m_pExplorer->AddRef() adds the reference count to 2.  m_pExplorer->Release() decreases the reference count to 1. m_pExplorer = NULL adds the reference count to 2 and then decreases the reference count to 1. But why does it causes the crash when m_pExplorer = NULL is called?

    Another question: After calling pSelection = m_pExplorer->GetSelection(), should pSelection->Release() be called to release pSelection pointer?

    Same question: After calling pIDispatch = pSelection->Item(index), should pIDispatch->Release() be called to release pIDispatch pointer?

    pSelection->Release() and pIDispatch->Release() are successful, but why does it causes the crash when pSelection = NULL and pIDispatch  = NULL is called?

    Why does the code work well in Outlook 2010 but not Outlook 2013? Are there any changes in Outlook 2013 OOM?

    Wednesday, November 14, 2012 3:17 PM
  • I understand that this is C++.

    By get() I was refering to std:auto_ptr<>.get() method which returns the underlying pointer to the COM object. You are not using raw COM pointers, you are using smart pointers.

    Once again, if you are using smart pointers, there is no reason to explicilty call AddRef/Release.

    If you prefer fine control over the reference counting, do not use smart pointers.

    Did you actually step into the line m_pExplorer = pExplorer?

    The answer to all of your other questions is yes.


    Dmitry Streblechenko (MVP)
    http://www.dimastr.com/redemption
    Redemption - what the Outlook
    Object Model should have been
    Version 5.4 is now available!

    Wednesday, November 14, 2012 6:27 PM
  • Thanks Dmitry. But I still want to know why the code works in Outlook 2010 but not Outlook 2013.
    Wednesday, November 14, 2012 6:48 PM
  • I would imagine Outlook 2010 did not pay any attention to the Explorerreference count and destroyed the Explorer objects when it saw fit.

    Dmitry Streblechenko (MVP)
    http://www.dimastr.com/redemption
    Redemption - what the Outlook
    Object Model should have been
    Version 5.4 is now available!


    Wednesday, November 14, 2012 7:18 PM