使用IXMLDOMDocument的正确方法

Proper way of using IXMLDOMDocument

本文关键字:方法 IXMLDOMDocument 使用      更新时间:2023-10-16

我正在尝试使用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);
}

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

  • S_OK的意思是"好的",
  • S_FALSE表示"正常,已初始化"或
  • RPC_E_CHANGED_MODE表示"错误,无法更改为新模式",并且引用计数不会增加。当您不主动需要公寓模式或多线程模式时,可以忽略这一点,但当您这样做时,您不得调用CoUnInitialize

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

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