c++ - ATL COM: Access Event Methods From Other Thread -


i'm implementing com interface existing vs2010 c++ mfc-application. parts of com interface interaction works great, confused of how trigger com events thread 1 com interface running / defined. application multi-threaded 1 main thread running com interface , handling gui changes (thread 1) , 1 thread receive incoming messages c-library (thread 2).

for messages received in thread 2 want notify com clients sending com event. have read many threads (firing com event thread 1 of them) , comarshalinterthreadinterfaceinstream / cogetinterfaceandreleasestream mentioned. using google can't seem find usage of these methods makes sense me; don't understand how implement these functions , if me.

relevant code parts:

testcom.idl: (the interface definition)

 interface itestcom: idispatch {     [id(1), helpstring("method test")] hresult test(); };  dispinterface _itestcomevents {     properties:     methods:         [id(1), helpstring("event executionover")] hresult testevent(); };  coclass testappcom {     [default] interface itestcom;     [default, source] dispinterface _itestcomevents; }; 

itestcomevents_cp.h (vs generated class connection points / events)

template<class t> class cproxy_itestcomevents :     public atl::iconnectionpointimpl<t, &__uuidof(_itestcomevents)> { public:     hresult fire_testevent()     {        hresult hr = s_ok;        t * pthis = static_cast<t *>(this);        int cconnections = m_vec.getsize();        (int iconnection = 0; iconnection < cconnections; iconnection++)        {           pthis->lock();           ccomptr<iunknown> punkconnection = m_vec.getat(iconnection);           pthis->unlock(); ... 

testcom.h (class implementing methods , cproxy_itestcomevents class)

class atl_no_vtable ctestcom :    public ccomobjectrootex<ccommultithreadmodel>,    public ccomcoclass<ctestcom, &clsid_testcom>,    public iconnectionpointcontainerimpl<ctestcom>,    public cproxy_itestcomevents<ctestcom>,    public idispatchimpl<imecappcom, &iid_itestcom, &libid_testlib, /*wmajor =*/ 1, /*wminor =*/ 0> { public:    static ctestcom * p_ctestcom;  ctestcom() {     p_ctestcom = this; } 

incoming.cpp (a class running on thread 2 should trigger event in following case statement)

case incoming_event_1: // trigger fire_testevent in thread 1 // ctestcom::p_ctestcom->fire_testevent(); trigger event on thread 2 

in code above can find current workaround problem create pointer object p_ctestcom allow class running on thread 1 trigger com events. thread 2 can access object trigger in thread 2, wouldn't work. solve methods defined in incoming.cpp post message (using postmessage()) thread 1 use p_ctestcom access , send com event. work, sure there must better (and safer) solution more accurately follows com design principles.

i shed light grateful!

roman r. provides options there better alternative, imo: can marshal listeners thread fires event. advising listeners typically done inside iconnectionpointimpl class in atl project, 'just' need modify default iconnectionpointimpl marshalling (e.g. via git simpler marshaling api).

the big advantage rest of code remains same before, no message passing or synchronization needed - generated *cp.h file needs updated.

the implementation discussed in microsoft knowledge base article kb280512 seems removed now, there improved implementation pj naughter can use replace default implementation.

here's version use, based on missing kb article. usage simple, rename class in generated cp.h file , modify m_vec.getat parts, described in gist have linked.


Comments

Popular posts from this blog

jquery - How can I dynamically add a browser tab? -

node.js - Getting the socket id,user id pair of a logged in user(s) -

keyboard - C++ GetAsyncKeyState alternative -