0

我必须处理一个使用 MSXML 将测量数据写入简单 XML 文件的遗留应用程序。基本上,这就是正在发生的事情:

MSXML2::IXMLDOMDocument2Ptr pXmlDocument;
HRESULT comResult = CXMLUtil::createXMLDocument(pXmlDocument);
// ... check HRESULT ...
MSXML2::IXMLDOMNodePtr pXmlMainNode = pXmlDocument.GetInterfacePtr();
MSXML2::IXMLDOMNodePtr pXmlSubNode = CXMLUtil::AppendNewElement(pXmlDocument, pXmlMainNode, RootTag, "");
// ... create further nodes ...
MSXML2::IXMLDOMNodePtr pXmlTmpNode = CXMLUtil::AppendNewElement(
pXmlDocument,
pXmlDataSetNode,
measDataTag,
measdata,
numberOfDataItems );
// ... append further items ...

在每个项目之后,pXmlTmpNode.Release()都会调用。pXmlDocument最后,所有其他节点以及Released.

createXMLDocument定义如下:

HRESULT CXMLUtil::createXMLDocument(MSXML2::IXMLDOMDocument2Ptr &pXmlDocument) {
    MSXML2::IXMLDOMDocument2 *xmlDocument = 0;
    HRESULT comError = CoCreateInstance(__uuidof(MSXML2::DOMDocument),NULL,CLSCTX_INPROC_SERVER,IID_PPV_ARGS(&xmlDocument));
    if (comError) return comError;
    xmlDocument->put_async(VARIANT_FALSE);
    xmlDocument->put_validateOnParse(VARIANT_FALSE);
    xmlDocument->put_resolveExternals(VARIANT_FALSE);
    xmlDocument->put_preserveWhiteSpace(VARIANT_TRUE);
    MSXML2::IXMLDOMDocument2Ptr ptr(xmlDocument);
    pXmlDocument = ptr;
    return comError;
}

对于附加新元素(即unsiged char数组),应用此函数:

MSXML2::IXMLDOMNodePtr CXMLUtil::AppendNewElement(MSXML2::IXMLDOMDocument2Ptr pXMLDom, MSXML2::IXMLDOMNodePtr pParent, CComBSTR strElementName, unsigned char* pData, long nData) {
    MSXML2::IXMLDOMNodePtr pData1 = pXMLDom->createElement(BSTR(strElementName));
    pData1->put_dataType(CComBSTR(_T("bin.base64")));
    SAFEARRAY* psa = SafeArrayCreateVector( VT_UI1, 0L, nData);
    psa->pvData = pData;
    VARIANT var;
    VariantInit(&var);
    var.parray = psa;
    var.vt = (VT_ARRAY | VT_UI1 );
    pData1->nodeTypedValue = var;
    pParent->appendChild(pData1);
    SafeArrayDestroy(psa);
    return pData1;
}

无论是使用#import <msxml4.dll>还是#import <msxml6.dll>使用,似乎都存在内存泄漏。由于measdataetc. 可能很大,这是一个相当大的问题。我可以做些什么来使代码正常工作吗?谢谢,马修

4

1 回答 1

2
MSXML2::IXMLDOMDocument2 *xmlDocument = 0;
HRESULT comError = CoCreateInstance(__uuidof(MSXML2::DOMDocument),
    NULL,CLSCTX_INPROC_SERVER,IID_PPV_ARGS(&xmlDocument));
...
MSXML2::IXMLDOMDocument2Ptr ptr(xmlDocument);
pXmlDocument = ptr;

此代码泄漏xmlDocumentptr(xmlDocument)做了一个额外的AddRef,但ReleasexmlDocument 没有超出范围。您在任何地方都使用智能 ptrs,没有理由不在这里也使用一个,可能是这样的:

MSXML2::IXMLDOMDocument2Ptr xmlDocument;
HRESULT comError = CoCreateInstance(__uuidof(MSXML2::DOMDocument),
    NULL,CLSCTX_INPROC_SERVER,IID_PPV_ARGS(&xmlDocument));
...
pXmlDocument = xmlDocument;
于 2013-12-03T11:05:49.807 回答