看流星社区

 找回密码
 注册账号
查看: 1759|回复: 0

用窗口消息解决COM接口的多线程访问问题

[复制链接]

该用户从未签到

发表于 2013-5-19 10:28:18 | 显示全部楼层 |阅读模式
上篇讲了COM接口的多线程访问问题,并用全局接口表的方法解决了。但有时候我们不能直接访问接口指针,而是通过一个封装类间接的访问。比如:
class SomeClass
{
private:
    IMyInterface *m_pInt;
public:
    void Method1()
    {
        //Init m_pInt
    }
    void Method2()
    {
        //call method of m_pInt
    }
}
我们只能访问SomeClass的公共方法,而无法直接访问接口指针,这时就不能使用使用全局接口表的方法。如果需要在不同线程中调用SomeClass的方法,唯一的办法就是把所有的调用放在一个线程中。怎么做到这一点呢?用一个消息窗口来同步是一个简单的方法。
首先定义一个窗口类,把所有对SomeClass的操作定义成窗口消息,如下:

#define WM_METHOD1 WM_USER + 100
#define WM_METHOD2 WM_USER + 101

class CThreadWnd : public CWindowImpl<CThreadWnd>
{
private:
    SomeClass m_someClass;
public:
BEGIN_MSG_MAP(CThreadWnd)
  MESSAGE_HANDLER(WM_METHOD1, OnMethod1)
  MESSAGE_HANDLER(WM_METHOD2, OnMethod2)
END_MSG_MAP()


LRESULT OnMethod1(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/);
LRESULT OnMethod2(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/);
}

在OnMethod1和OnMethod2中完成对m_someClass的方法调用,如果方法有参数,通过wParam和lParam传递。

然后,我们需要做的是在一个线程中创建这个窗口。并在需要调用SomeClass的方法时,通过向CThreadWnd窗口发送消息间接完成。例如:

CThreadWnd wndThread;

//In thread A
wndThread.SendMessage(WM_METHOD1);

//In thread B
wndThread.SendMessage(WM_METHOD2);

至于wndThread,可以保存在任何地方。而创建线程窗口的线程函数代码基本上应该是这样的:

UINT WINAPI ThreadProc(LPVOID lpParam)
{
    ::CoInitialize(0);

    CThreadWnd    *pWnd = (CThreadWnd*)lpParam;

    CMessageLoop theLoop;
    _Module.AddMessageLoop(&theLoop);

    pWnd->Create(NULL, CRect(0, 0, 0, 0), NULL, WS_POPUP);

    theLoop.Run();

    pWnd->DestroyWindow();

    _Module.RemoveMessageLoop();

    ::CoUninitialize();

    return 0;
}

创建线程的代码就不贴了,销毁线程则只要向线程窗口发送WM_QUIT消息即可。这个方法在实际应用中个人感觉非常有效。
有一个问题是当方法参数比较多时,很难通过wParam和lParam传递。这就需要另外定义一个结构,存放各种参数,然后通过wParam传递结构的地址。总之人是活的,灵活运用:P
点击按钮快速添加回复内容: 支持 高兴 激动 给力 加油 苦寻 生气 回帖 路过 感恩
您需要登录后才可以回帖 登录 | 注册账号

本版积分规则

小黑屋|手机版|Archiver|看流星社区 |网站地图

GMT+8, 2024-5-15 09:57

Powered by Kanliuxing X3.4

© 2010-2019 kanliuxing.com

快速回复 返回顶部 返回列表