gpt4 book ai didi

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

转载 作者:太空狗 更新时间:2023-10-29 21:24:17 26 4
gpt4 key购买 nike

我正在为现有的 VS2010 C++ MFC 应用程序实现一个 COM 接口(interface)。 COM 接口(interface)交互的大部分工作都很好,但我对如何从运行/定义 COM 接口(interface)的线程的另一个线程触发 COM 事件感到困惑。该应用程序是多线程的,其中一个主线程运行 COM 接口(interface)并处理 GUI 更改(线程 1),另一个线程接收来自 C 库的传入消息(线程 2>).

对于在线程 2 中收到的某些消息,我想通过发送 COM 事件来通知 COM 客户端。我读过很多主题(Firing COM Event From Another Thread 是其中之一)和 CoMarshalInterThreadInterfaceInStream/CoGetInterfaceAndReleaseStream被提及。使用谷歌我似乎无法找到对我有意义的这些方法的任何用法;我只是不明白如何实现这些功能以及它们是否真的对我有帮助。

相关代码部分:

TestCOM.idl:(接口(interface)定义)

 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 设计原则。

我将不胜感激!

最佳答案

Roman R. 提供了一些不错的选择,但还有一个更好的选择,IMO:您可以将监听器编码到触发事件的线程。由于建议听众通常在 ATL 项目的 IConnectionPointImpl 类中完成,您“只需”修改默认的 IConnectionPointImpl 来为您进行编码(例如,通过 GIT比编码 API 更简单)。

最大的优势是其余代码几乎与以前相同,因此不需要消息传递或同步 - 只需要更新生成的 *CP.h 文件。

Microsoft 知识库文章 KB280512 中讨论了该实现,该文章现在似乎已被删除,但有一个 improved implementation by PJ Naughter 可用于替换默认实现。

Here's the version that I use ,基于缺少的知识库文章。用法很简单,只需重命名 class in the generated CP.h file 并修改 m_vec.GetAt 部分,如我链接的要点中所述。

关于c++ - ATL COM : Access Event Methods From Other Thread,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16552418/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com