我正在實現一個COM接口到現有的VS2010 C++ MFC應用程序。 COM接口交互的大部分工作很好,但是我很困惑如何從COM接口運行/定義的另一個線程觸發COM事件。該應用程序是多線程的,其中一個主線程運行COM接口並處理GUI更改(線程1)和一個線程以接收來自C庫(線程2)的傳入消息。ATL COM:從其他線程訪問事件方法
對於線程2中收到的某些消息,我想通過發送COM事件來通知COM客戶端。我讀過很多線索(Firing COM Event From Another Thread就是其中之一),並提到了CoMarshalInterThreadInterfaceInStream/CoGetInterfaceAndReleaseStream。使用谷歌我似乎無法找到任何對我有意義的方法,我只是不明白如何實現這些功能,如果他們真的會幫助我。
相關代碼部分:
TestCOM.idl:(接口定義)
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生成的類爲連接點/事件)
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();
for (int iConnection = 0; iConnection < cConnections; iConnection++)
{
pThis->Lock();
CComPtr<IUnknown> punkConnection = m_vec.GetAt(iConnection);
pThis->Unlock();
...
TestCOM.h(類實現的方法和CProxy_ITestCOMEvents類)
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(上線運行2類應該觸發在接下來的case語句事件)
case INCOMING_EVENT_1:
// Trigger Fire_TestEvent in thread 1
// CTestCOM::p_CTestCOM->Fire_TestEvent(); trigger event on thread 2
在你上面的代碼可以找到我目前的解決方法,這個問題是創建一個指針對象p_CTestCOM,它允許線程1上運行的任何類來觸發COM事件。線程2可以訪問該對象,但它會在線程2中觸發它,這不起作用。爲了解決這個問題,Incoming.CPP中定義的所有方法都可以將一條消息(使用PostMessage())發佈到線程1,這將使用p_CTestCOM來訪問和發送COM事件。這是行得通的,但我確定必須有更好的(更安全的)解決方案,更準確地遵循COM設計原則。
我有人可以擺脫一些光,我將不勝感激!
您正在尋找的技術稱爲*編組*。我原以爲它只是在進程之間,但它似乎也可用於線程。請參閱初學者http://support.microsoft.com/kb/206076 –
我成功使用GIT編組並收到指向我的ITestCOM界面的指針。但是,我無法從ITestCOM接口訪問Fire_TestEvent()事件,我不希望強制將公共方法添加到只會觸發事件的COM庫(如HRESULT TriggerTestEvent();)。有什麼方法可以訪問Fire_Event方法或在庫中創建只有應用程序可以訪問的私有方法,而不是任何客戶端? – Pettor