正确使用IXMLDOMDocument的方法

时间:2013-09-11 07:37:55

标签: c++ dom memory-leaks com

我正在尝试使用IXMLDOMDocument进行XML读/写。我不是很好的COM,我不知道我做的是对还是错。我很不确定COM初始化和重新启动可能存在一些问题。这是我下面的代码,让我知道如果由于COM,这里有任何可能的错误/内存泄漏。

void MyClass::ReadXML(BSTR *pVal)
{
    IXMLDOMDocument * pXMLDoc;
    IXMLDOMNode * pXDN;

    HRESULT hr = CoInitialize(NULL); 
    hr = CoCreateInstance(CLSID_DOMDocument, NULL, CLSCTX_INPROC_SERVER, 
       IID_IXMLDOMDocument, (void**)&pXMLDoc);

    if (SUCCEEDED(hr))
    {
        IXMLDOMNode* pEntityNode = CDOMHelpers::InsertDOMElement(pDoc, NULL, L"Person", NULL);

        if (SUCCEEDED(hr))
        {
            SomeClassObject->SerializeXML(pXMLDoc, pXDN);
            pXMLDoc->get_xml(pVal);
            pXDN->Release();       // Is this proper way to release COM?
            pXDN = NULL;
            pXMLDoc->Release();
            pXMLDoc = NULL;
        }
    }
}

void SomeOtherClass::SerializeXML(IXMLDOMDocument* pDoc, IXMLDOMNode* pXDN)
{
    CStringW text;
    IXMLDOMNode* pNewNode;

    text.Format(L"%u", Name);
    pNewNode = CDOMHelpers::InsertDOMElement(pDoc, pEntityNode, L"Name", text);

    text.Format(L"%u", Address);
    pNewNode = CDOMHelpers::InsertDOMElement(pDoc, pEntityNode, L"Address", text);
}

1 个答案:

答案 0 :(得分:0)

MyClass::ReadXML中,调用CoInitialize会有潜在危险。当你不检查返回值时,调用者可能已在此线程上调用它,这会导致问题。 您需要为每个成功的CoUnInitialize致电CoInitialize

  • S_OK表示“确定”,
  • S_FALSE表示“确定,已初始化”或
  • RPC_E_CHANGED_MODE表示“错误,无法更改为新模式”,并且引用计数不会递增。当您不主动要求分区模式或多线程模式时,可以忽略这一点,但是当你这样做时不能调用CoUnInitialize

因此,最好的方法是RAII-Object,其c'tor调用CoInitialize并监视返回值,并且只在需要时才调用CoUnInitialize

参考: http://msdn.microsoft.com/en-us/library/windows/desktop/ms695279%28v=vs.85%29.aspx