打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
vs2008 ATL 非主线程(用户线程)调用Fire_ 出现错误

ATL(ActiveX)中用户线程与主线程之间的交互,可以通过两种方法实现:

1、消息机制:此需要一个隐藏窗口支持;

2、线程监听传递消息(主线程、用户线程),多数建议使用_beginthreadex(...)进行线程的创建

 

 

下面主要介绍第二种方法:其实现大致有三种

1、容器-》连接点-》相应的接口函数(例如:onClickbutton())中,启用线程;  容器可以控制线程的创建

2、如果线程的创建都是由插件来进行管理,则可以再FinalConst 里面可以进行线程的创建

 

线程具体创建方法

1、接口函数来创建

     注意onClickbutton()是接口类COsip_Ax的一个成员函数,

     在成员函数中启用线程threadtask(),则此threadtask()必须满足两个条件1、为COsip_Ax的成员函数  2、静态函数;

     其调用大致如下

      在类中定义:

      static unsigned __stdcall osip_zh_thread_event(LPVOID arg);  必须要定位为static   否则不能再接口函数中触发

      具体实现:

       unsigned __stdcall COsip_Ax::osip_zh_thread_event(LPVOID arg)

      在此函数中,可以调用Fire_XXX_Event()    

2、FinalConst 创建

 

 a、static unsigned __stdcall osip_zh_thread_inclass_public_static(LPVOID arg);//LPVOID arg
 friend unsigned __stdcall osip_zh_thread_friend(LPVOID arg);//友元函数实际上不属于任何类

b、hThread = (HANDLE)_beginthreadex(NULL,NULL,osip_zh_thread_outclass,this,NULL,&threadID);  //与类无关,不能调用类中对象和函数
c、hThread = (HANDLE)_beginthreadex(NULL,NULL,osip_zh_thread_inclass_friend,this,NULL,&threadID);//友元函数,可以调用类中的对象和函数

 

其中a和c能够直接对Fire_XXX_Event函数进行操作。

 

 

但是vs2008中自动生成的代码中,能够调用Fire_XXX_Event()   ,但是实际上不能触发里面的Invoke函数,必须做如下的修改:

 下载:#include "ATLCPImplMT.h" 文件    //http://support.microsoft.com/kb/280512

把事件接口文件 XXX_CP.h修改如下

 template<class T>
class CProxy_IOsip_AxEvents :
// public IConnectionPointImpl<T, &__uuidof(_IOsip_AxEvents)>
 public IConnectionPointImplMT<T, &__uuidof(_IOsip_AxEvents),CComDynamicUnkArray>

同时必须修改两处:

其一:

在VS2008中会有调用静态函数的错误,需要在修改ATLCPImplMT.h

DWORD dwGITCookie = (DWORD)_CDV::GetUnknown(dwCookie);修改为
DWORD dwGITCookie = (DWORD)m_vec.GetUnknown(dwCookie);
pend->dwCookie = _CDV::GetCookie(reinterpret_cast<IUnknown **>(pDWCookie));修改为
pend->dwCookie = m_vec.GetCookie(reinterpret_cast<IUnknown **>(pDWCookie));

其二:(待验证,貌似好几种都可以用)

改下面:pT->Lock();CComPtr<IUnknown> sp = m_vec.GetAt(nConnectionIndex);pT->Unlock();           
改成:CComPtr<IUnknown> sp;sp.Attach (GetInterfaceAt(nConnectionIndex));

    IDispatch * pConnection = static_cast<IDispatch *>(punkConnection.p);
   //IDispatch * pConnection = reinterpret_cast<IDispatch*>(punkConnection.p);
   //CComQIPtr< IDispatch > pConnection( punkConnection );


经过上述的修改,就可以实现 在新线程中,调用Fire_XX_Event(),并能够成功触发!


 

 

 

//传递unsigned char的方法如下
     //avarParams[0].byref = "a";//result;
     //avarParams[0].vt = VT_VARIANT;//VT_I1|VT_BYREF;
//传递字符串
   //avarParams[0] = param;   //(char * param)

 
本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
在Delphi中使用IDispatch访问MSHTML的一些经验
在linux c++类中的成员函数里创建多线程要注意的地方(转)
深入剖析WTL
exosip 对比osip
Linux操作系统下实现多线程客户/服务器
关于回调函数和this指针探讨
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服