简体   繁体   中英

Proper way of using IXMLDOMDocument

I am trying to use IXMLDOMDocument for XML reading/writing. I am not good COM, and I am not aware that I am doing things right or wrong. I am very unsure that there could be some problems with COM initialization and relase. Here is my code below and let me know If there are any possibles bugs / memory leaks here due to 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);
}

In MyClass::ReadXML it is potentially dangerous to call CoInitialize. The Caller could have already called it on this thread, which leads to problems, when you do not check the return value. You need to call CoUnInitialize for each successful CoInitialize :

  • S_OK meaning "OK",
  • S_FALSE meaning "OK, was already initialized" or
  • RPC_E_CHANGED_MODE meaning "ERROR, Can not change to new mode" and the reference-count is not incremented. You can ignore this, when you do not actively require appartment mode or multithreaded mode, but you must not call CoUnInitialize when you do.

So, the best way would be a RAII-Object whose c'tor calls CoInitialize and monitors the return value, and whose d'tor calls CoUnInitialize only when needed.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM