Рассмотрим следующий сценарий:COM объект Срок службы
Этот код выполняется по нити A:
CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED);
globalSomeSTAComObject.CreateInstance((__uuidof(CLSID_SomeSTAComObject));
return 0;
Теперь после того, как поток А делается это исполнение делает default STA
«наследовать» globalSomeSTAComObject и он может быть использован другие темы?
Или этот объект становится непригодным?
Тот же вопрос относительно потока A, но теперь рассмотрим объект как объект MTA Com, который был создан в потоке MTA.
Когда поток А выполнен, выполняется ли объект MTA Com еще в пределах Multithreaded Apartment
и может использоваться?
MSXML2::IXMLDOMDocumentPtr xml;
unsigned __stdcall CreateXml(void*)
{
CoInitializeEx(nullptr, COINIT_MULTITHREADED);
xml.CreateInstance(__uuidof(MSXML2::FreeThreadedDOMDocument60));
xml->load("c:\\test.xml");
return 0;
}
int _tmain(int argc, _TCHAR* argv[])
{
CoInitializeEx(nullptr, COINIT_MULTITHREADED);
HANDLE handle = reinterpret_cast<HANDLE>(_beginthreadex(nullptr, 0, CreateXml, nullptr, 0, nullptr));
WaitForSingleObject(handle, INFINITE);
long numOfSections = xml->documentElement->childNodes->length; //This works why ?
xml.Release();
CoUninitialize();
return 0;
}
Пожалуйста, не в CreateXml
я намеренно не называю CoUninitialize
, потому что я хочу знать, что это состояние объекта XML в этом сценарии.
Показанный снимок кода опасен. Не только вы не показываете, как вы собираетесь делать «CoUnitinialize», но вы также делаете определенные предположения об использовании специального указателя COM STA как для других потоков, так и после завершения STA/thread. 'globalSomeSTAComObject' может использоваться только в этом потоке и перед' CoUnitinialize'. Использование на других потоках может работать, но, как правило, неверно, и поведение не определено. –
Если поток MTA создает объект MTA (глобальный объект) и завершается. Является ли объект еще «живым» в квартире MTA? Или в этом случае поведение не определено? – JobNick
COM требует, чтобы вы прекратили свою деятельность COM перед вызовом 'CoUninitialize'. Следовательно, оставление COM-указателя вне этой инициализации неверно. Однако в случае MTA это гораздо менее частая проблема, поскольку указатель все еще действителен в присутствии любого другого потока MTA. В общем, вы иногда можете оставить COM-объект «просочившимся» из вспомогательного потока MTA, но суммируя все, я бы сказал, что вы все еще неправильно задаете свой вопрос. На первом месте есть что-то не так, пытаясь иметь объект singleton COM вне инициализации COM. –