0

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

1 回答 1

0

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

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

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

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

于 2013-09-11T09:48:10.677 回答