c++ - Why is my Qt application crashing when accessing the IWMPMedia interface? -
i have built qt (5.7) application interfaces windows media player com api parse track meta data. in-explicit reason application crashing when calling iwmpmedia3::getattributecountbytype
.
the line crash keeps occurring is:
if (pmedia3item && pmedia3item->getattributecountbytype(l"trackingid", 0, &l) == s_ok) //will crash here
it not crash on first instance, takes couple of hundred loops , seems connected when call repeatedly returns 0
. if switch attribute know exists runs fine.
what posted below object stripped right back, still crashes. object designed run in own qthread
, com symbols defined , contained within qthread
.
the code forms part of larger app makes use of many other qt modules, gui, web engine being 2 of biggest.
#include "wmpmlimport.h" #include <qdebug> #include "wininet.h" #define wmp_clsid l"{6bf52a52-394a-11d3-b153-00c04f79faa6}" #define wmp_refiid l"{d84cca99-cce2-11d2-9ecc-0000f8085981}" #define wmp_pl_all_music l"all music" #define safe_release(ptr) if(null!=(ptr)){(ptr)->release();ptr=null;} #define bstr_release(bstr) {sysfreestring(bstr);(bstr)=null;} class ccoinitialize { public: ccoinitialize() : m_hr(coinitialize(null)) {} ~ccoinitialize() { if(succeeded(m_hr)) { qdebug() << "ccoinitialize: dtor"; couninitialize(); } } hresult m_hr; }; /** worker class step through wmp com interface , extact audio meta data contained within it, */ class wmpmlcomhandler : public qobject { public: wmpmlcomhandler(wmpmlimport* t) : m_thread(t) { qdebug() << "wmpmlcomhandler::ctor" << qthread::currentthreadid(); } ~wmpmlcomhandler() { qdebug() << "wmpmlcomhandler::dtor" << qthread::currentthreadid(); } /** method responsible walking through com interface , extracting track , playlist metadata including artwork. @returns return false if com api not parsed correctly. */ bool parse() { bool b = true; ccoinitialize ccoinit; iwmpcore* piwmpcore = null; iwmpcore3* piwmpcore3 = null; iwmpplaylistcollection *pplaylistcollection; iwmpplaylist *pmainlibplaylist; clsid clsid; clsid refid; clsidfromstring(wmp_clsid, &clsid); clsidfromstring(wmp_refiid, &refid); if(succeeded(cocreateinstance(clsid, null, clsctx_all, refid, (void**)&piwmpcore))) { if(succeeded(piwmpcore->get_playlistcollection(&pplaylistcollection))) { if(succeeded(piwmpcore->queryinterface(__uuidof(iwmpcore3), reinterpret_cast<void**>(&piwmpcore3)))) { iwmpplaylistarray* pplaylistarray = null; if(succeeded(pplaylistcollection->getall(&pplaylistarray))) { long playlistcount = 0; if(succeeded(pplaylistarray->get_count(&playlistcount))) { iwmpplaylist* pplaylist = null; for(int playlistindex=0; playlistindex < playlistcount; playlistindex++) { if (succeeded(pplaylistarray->item(playlistindex, &pplaylist))) { long lmediacount = 0; if (succeeded(pplaylist->get_count(&lmediacount))) { fetchplaylist(pplaylist, null, playlistindex, lmediacount); } safe_release(pplaylist); } } } safe_release(pplaylistarray); } safe_release(piwmpcore3); } safe_release(pplaylistcollection); } safe_release(piwmpcore); } safe_release(pmainlibplaylist); return b; } private: void fetchplaylist(iwmpplaylist* pplaylist, bstr bstrname, unsigned int playlistindex, long count) { //get playlist items for(long mediaindex=0; mediaindex<count-1; mediaindex++) { iwmpmedia* pmediaitem = null; if(succeeded(pplaylist->get_item(mediaindex, &pmediaitem))) { iwmpmedia3 *pmedia3item = null; if (pmediaitem->queryinterface(__uuidof(iwmpmedia3), reinterpret_cast<void **>(&pmedia3item)) == s_ok) { long l = 0; qdebug() << "about call method for" << mediaindex << "time"; if (pmedia3item && pmedia3item->getattributecountbytype(l"trackingid", 0, &l) == s_ok) //will crash here { qdebug() << "exited method for" << mediaindex << "time"; } } safe_release(pmedia3item); safe_release(pmediaitem); } } qdebug() << "*********complete*********"; } wmpmlimport* m_thread; }; //== wmpmlimport::wmpmlimport() : m_comhandler(null) { qdebug() << "wmpmlimporter ctor" << qthread::currentthreadid(); } wmpmlimport::~wmpmlimport() { } /** reimplemented function runs function contents in new thread context. parsing of com ran through thread. returning out of thread end execution. */ void wmpmlimport::run() { qmutexlocker g(&m_lock); m_comhandler = new wmpmlcomhandler(this); g.unlock(); bool parseok = m_comhandler->parse(); g.relock(); delete m_comhandler; m_comhandler = null; }
Comments
Post a Comment