В чем ошибка?
От: Xenia США  
Дата: 18.09.02 19:39
Оценка:
Имеется таой код:

    CGXData *pData = m_MZGridWnd.GetParam()->GetData();
    CoInitialize(NULL);
    
    
    MSXML2::IXMLDOMDocumentPtr m_Output("MSXML2.DOMDocument.3.0");
    bool ret = m_Output->load("output1.xml");

    
    MSXML2::IXMLDOMNodePtr rootElement =
         m_Output->selectSingleNode("doc");
    for (int i=1; i<=CurrentRow; i++)
    {
    
        MSXML2::IXMLDOMNodePtr childNode =
            m_Output->createNode(CComVariant(NODE_ELEMENT),"Nom","");
        rootElement->appendChild(childNode);
        MSXML2::IXMLDOMElementPtr childElement = childNode;
        childElement->setAttribute("Mnemo",    CComVariant(pData->GetValueRowCol(i,1)));
        childElement->setAttribute("FullName", CComVariant(pData->GetValueRowCol(i,2)));
        childElement->setAttribute("Model",    CComVariant(pData->GetValueRowCol(i,3)));
        childElement->setAttribute("Price",    CComVariant(pData->GetValueRowCol(i,4)));
        childElement->setAttribute("SN",       CComVariant(pData->GetValueRowCol(i,8)));
    }

    

    m_Output->save("res.xml");
    _bstr_t bstrXML=L"";
    CString sXML="";
    bstrXML=m_Output->xml;
    sXML = (const char*)bstrXML;
    int b= sXML.Replace("><",">\n<");
    bstrXML = (LPCTSTR)sXML;
    m_Output->loadXML(bstrXML);
    m_Output->save("res.xml");
    CoUninitialize(); 


На строчке CoUninitialize() вываливается ексепшн, но файл формируется правильно, если строчку закомментировать то видимых проявлений ошибки нет никаких. Вопрос — в чем тут дело и как вообще в этом коде организовать обработку ошибок — возврата проверять, если да то какие, или как.
Re: В чем ошибка?
От: Igor Soukhov  
Дата: 18.09.02 19:53
Оценка:
Здравствуйте Xenia, Вы писали:

X>Имеется таой код:


X>На строчке CoUninitialize() вываливается ексепшн, но файл формируется правильно, если строчку закомментировать то видимых проявлений ошибки нет никаких. Вопрос — в чем тут дело и как вообще в этом коде организовать обработку ошибок — возврата проверять, если да то какие, или как.


наиболее вероятно что валится после CoUnitialize когда после деинициализации
делаются Release для указателей внутрях SmartPointer-ов (когда вызываются их деструкторы)
* thriving in a production environment *
Re[2]: В чем ошибка?
От: IT Россия linq2db.com
Дата: 18.09.02 19:58
Оценка: 22 (2)
Здравствуйте Igor Soukhov, Вы писали:

IS>наиболее вероятно что валится после CoUnitialize когда после деинициализации делаются Release для указателей внутрях SmartPointer-ов (когда вызываются их деструкторы)


Даже не вероятно, а так и есть. Сделай так:

CoInitialize(NULL);
{
    // весь код здесь
}
CoUninitialize();


А ещё лучше обернуть всё как и положено в try/catch

CoInitialize(NULL);
try {
    // весь код здесь
} catch (_com_error er) {
    // вывод сообщения об обшибке
}
CoUninitialize();
Если нам не помогут, то мы тоже никого не пощадим.
Re: В чем ошибка?
От: DarkGray Россия http://blog.metatech.ru/post/ogni-razrabotki.aspx
Дата: 18.09.02 19:58
Оценка: 22 (2)
Здравствуйте Xenia, Вы писали:

X>Имеется таой код:


X>
X>    CGXData *pData = m_MZGridWnd.GetParam()->GetData();
X>    CoInitialize(NULL);
X>
  //...    
X>    
X>    MSXML2::IXMLDOMDocumentPtr m_Output("MSXML2.DOMDocument.3.0");
X>    CoUninitialize(); 
X>


Проблема в том, что деструктор для MSXML2::IXMLDOMDocumentPtr вызывается после CoUninitialize() и при этом в этом вызове используются вещи уже убитые CoUninitialize-ом.

Для того, чтобы это не происходило, надо код между CoInitialize & CoUninitialize() заключить в фигурные скобочки или вынести CoInitialize/CoUninitialize() в отдельную класс оболочку
    CoInitialize(NULL);
        {

  //...    
    
    MSXML2::IXMLDOMDocumentPtr m_Output("MSXML2.DOMDocument.3.0");
        }
    CoUninitialize();
Re: В чем ошибка?
От: old Dutchman Беларусь http://blogs.rsdn.org/ikemefula
Дата: 19.09.02 07:24
Оценка:
Здравствуйте Xenia, Вы писали:


X>
X>    CGXData *pData = m_MZGridWnd.GetParam()->GetData();
X>    CoInitialize(NULL);
X>    
X>    
X>    MSXML2::IXMLDOMDocumentPtr m_Output("MSXML2.DOMDocument.3.0");
X>    bool ret = m_Output->load("output1.xml");

X>    
X>    MSXML2::IXMLDOMNodePtr rootElement =
X>         m_Output->selectSingleNode("doc");
X>    for (int i=1; i<=CurrentRow; i++)
X>    {
X>    
X>        MSXML2::IXMLDOMNodePtr childNode =
X>            m_Output->createNode(CComVariant(NODE_ELEMENT),"Nom","");
X>        rootElement->appendChild(childNode);
X>        MSXML2::IXMLDOMElementPtr childElement = childNode;
X>        childElement->setAttribute("Mnemo",    CComVariant(pData->GetValueRowCol(i,1)));
X>        childElement->setAttribute("FullName", CComVariant(pData->GetValueRowCol(i,2)));
X>        childElement->setAttribute("Model",    CComVariant(pData->GetValueRowCol(i,3)));
X>        childElement->setAttribute("Price",    CComVariant(pData->GetValueRowCol(i,4)));
X>        childElement->setAttribute("SN",       CComVariant(pData->GetValueRowCol(i,8)));
X>    }

X>    

X>    m_Output->save("res.xml");
X>    _bstr_t bstrXML=L"";
X>    CString sXML="";
X>    bstrXML=m_Output->xml;
X>    sXML = (const char*)bstrXML;
X>    int b= sXML.Replace("><",">\n<");
X>    bstrXML = (LPCTSTR)sXML;
X>    m_Output->loadXML(bstrXML);
X>    m_Output->save("res.xml");

// сюда нужно поместить все ->Release().

m_Output->Release() // вот так


X>    CoUninitialize(); 
X>


Эксцепшн означает неосвобожденные ссылки. Потому и такая дрянь.
Эта ситуация происходит потому, что ты пользуешься смартпоинтерами. Деструкторы срабатывают после CoUninitialize() — поэтому на момент вызова они еше не освободили ссылки.


X>На строчке CoUninitialize() вываливается ексепшн, но файл формируется правильно, если строчку закомментировать то видимых проявлений ошибки нет никаких. Вопрос — в чем тут дело и как вообще в этом коде организовать обработку ошибок — возврата проверять, если да то какие, или как.
Re: В чем ошибка?
От: RRiver  
Дата: 18.10.02 09:44
Оценка:
Столкнулся с подобной проблемой, оказалось что релиз пойнтеров надо делать в обртном порядке, тогда все нормально работает!
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.