惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
C
Cisco Blogs
Simon Willison's Weblog
Simon Willison's Weblog
Latest news
Latest news
P
Palo Alto Networks Blog
T
The Exploit Database - CXSecurity.com
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
AI
AI
阮一峰的网络日志
阮一峰的网络日志
量子位
Project Zero
Project Zero
Know Your Adversary
Know Your Adversary
Google Online Security Blog
Google Online Security Blog
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
S
Schneier on Security
大猫的无限游戏
大猫的无限游戏
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
K
Kaspersky official blog
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
V
Visual Studio Blog
Spread Privacy
Spread Privacy
C
CERT Recently Published Vulnerability Notes
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
S
SegmentFault 最新的问题
Hugging Face - Blog
Hugging Face - Blog
W
WeLiveSecurity
博客园 - Franky
Last Week in AI
Last Week in AI
博客园 - 聂微东
博客园 - 三生石上(FineUI控件)
小众软件
小众软件
IT之家
IT之家
I
Intezer
The Cloudflare Blog
月光博客
月光博客
N
News | PayPal Newsroom
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
V
V2EX
博客园_首页
罗磊的独立博客
NISL@THU
NISL@THU
爱范儿
爱范儿
Jina AI
Jina AI
有赞技术团队
有赞技术团队
The Hacker News
The Hacker News
A
Arctic Wolf
Scott Helme
Scott Helme
Engineering at Meta
Engineering at Meta
P
Proofpoint News Feed

博客园 - vibration

ATL3.0组件注册bug的解决方法 奇怪的引用错误及解决方法 OLE2T在VS2003中转换中文失败的问题及解决方法 标题栏按钮的WTL实现 AppBar的WTL实现 招聘C++和C#开发工程师 ATL组件中文路径注册问题(转载) 关于C++模板的连接问题 - vibration - 博客园 用全局接口表实现COM接口在不同线程中的传递 MyMSN支持自定义内容了 自画菜单的WM_MEASUREITEM只会发送一次 悼念皮皮 上了点照片 一个测试记忆力的小游戏 老板该如何向核心员工许诺 ActiveScript SkinX界面换肤框架更新 反射获取定制Attribute Skin技术实现框架(完)
用窗口消息解决COM接口的多线程访问问题
vibration · 2005-06-02 · via 博客园 - vibration

上篇讲了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 + 101class 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(0000), NULL, WS_POPUP);

    theLoop.Run();

    pWnd

->DestroyWindow();

    _Module.RemoveMessageLoop();

    ::CoUninitialize();

return 0;
}

创建线程的代码就不贴了,销毁线程则只要向线程窗口发送WM_QUIT消息即可。这个方法在实际应用中个人感觉非常有效。
有一个问题是当方法参数比较多时,很难通过wParam和lParam传递。这就需要另外定义一个结构,存放各种参数,然后通过wParam传递结构的地址。总之人是活的,灵活运用:P