我正在为现有的 VS2010 C++ MFC 应用程序实现 COM 接口。COM 接口交互的大多数部分工作得很好,但我对如何从运行/定义 COM 接口的另一个线程触发 COM 事件感到困惑。该应用程序是多线程的,一个主线程运行 COM 接口并处理 GUI 更改(线程 1),一个线程接收来自 C 库的传入消息(线程 2)。
对于线程 2 中收到的某些消息,我想通过发送 COM 事件来通知 COM 客户端。我已经阅读了许多线程(从另一个线程触发 COM 事件就是其中之一)并且提到了CoMarshalInterThreadInterfaceInStream / CoGetInterfaceAndReleaseStream。使用 Google,我似乎找不到对我有意义的这些方法的任何用法;我只是不明白如何实现这些功能,以及它们是否真的会帮助我。
相关代码部分:
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 中定义的所有方法都可以向线程 1 发布消息(使用 PostMessage()),线程 1 将使用 p_CTestCOM 访问和发送 COM 事件。这会起作用,但我确信必须有一个更好(更安全)的解决方案,更准确地遵循 COM 设计原则。
我有人可以提供一些启示,我将不胜感激!