[英]Data being lost when sent via a different thread over COM server - previously worked in VC6, now broken in VS2010
从VC6转换到VS2010时,我遇到了很多小问题,但是解决这一问题时遇到了问题。 下面是将数据从我的类发送到COM服务器时使用的委托。
编辑2:添加了代码以检查varResult。
HRESULT Fire_Msg(BSTR Msg)
{
CComVariant varResult;
T* pT = static_cast<T*>(this);
int nConnectionIndex;
CComVariant* pvars = new CComVariant[1];
int nConnections = m_vec.GetSize();
for (nConnectionIndex = 0; nConnectionIndex < nConnections; nConnectionIndex++)
{
pT->Lock();
CComPtr<IUnknown> sp = m_vec.GetAt(nConnectionIndex);
pT->Unlock();
IDispatch* pDispatch = reinterpret_cast<IDispatch*>(sp.p);
if (pDispatch != NULL)
{
pvars[0] = Msg;
DISPPARAMS disp = { pvars, NULL, 1, 0 };
pDispatch->Invoke(0x1, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, &disp, &varResult, NULL, NULL);
}
}
delete [] pvars;
// Changed to display what happens to varResult.
if (varResult.scode != S_OK)
{
// Do some error handling... (later)
return varResult.scode;
}
else
{
return varResult.scode;
}
}
编辑2:从工作或不工作,varResult返回S_OK。 没有不同。
当我在此行中断时,从主进程或线程发送时,数据看起来正确:
pDispatch->Invoke(0x1, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, &disp, NULL, NULL, NULL);
编辑:我有工作和不工作的图片。 它实际上只是表明,从从threadex启动的线程进行调用时,数据已在“ disp”中正确设置,并且在执行“ pDispatch-> Invoke”时没有问题。
非工作: :结束编辑
在另一个应用程序中,我有以下代码来回答调度的数据:
BEGIN_DISPATCH_MAP(CGenRTEvent, CCmdTarget)
//{{AFX_DISPATCH_MAP(CGenRTEvent)
DISP_FUNCTION(CGenRTEvent, "OnMsgStr", OnMsgStr, VT_EMPTY, VTS_BSTR)
DISP_FUNCTION(CGenRTEvent, "OnMsg", OnMsg, VT_EMPTY, VTS_BSTR)
DISP_FUNCTION(CGenRTEvent, "OnEndRun", OnEndRun, VT_EMPTY, "")
DISP_FUNCTION(CGenRTEvent, "OnProgress", OnProgress, VT_EMPTY, VTS_I4 VTS_BSTR)
DISP_FUNCTION(CGenRTEvent, "OnISocket", OnISocket, VT_EMPTY, VTS_BSTR)
// DISP_FUNCTION(CGenRTEvent, "OnMsg", OnMsg, VT_EMPTY, VTS_PVARIANT)
//}}AFX_DISPATCH_MAP
END_DISPATCH_MAP()
BEGIN_INTERFACE_MAP(CGenRTEvent, CCmdTarget)
INTERFACE_PART(CGenRTEvent, DIID__IGenRTEvents, Dispatch)
END_INTERFACE_MAP()
void CGenRTEvent::OnMsgStr(LPCTSTR strMsg)
{
m_pFrame->OnMsgStr(strMsg);
}
从主线程(在第一个应用程序内部)使用时,会正确引发OnMsgStr。 从其他线程完成时,永远不会引发OnMsgStr。 这在VC6中一直运行良好,但是VS2010不喜欢它。
编辑:我的问题是,如何防止数据丢失? 我相当确定原因与从另一个线程调用此事件有关,但不知道如何解决。
任何建议或意见表示赞赏吗?
提前致谢。
在Paulo Madeira的慷慨帮助下,我能够通过搜索KB280512来解决此问题,这使我进入了由PJ Naughter编写的名为GPSCom的项目。 链接在这里http://www.naughter.com/gpscom2.html 。 我下载了他的代码,他提供了一个名为“ ATLCPImplMT.h”的免费软件,可以未经修改就以任何形式使用。 根据他的示例,我将代码修改如下:
HRESULT Fire_Msg(BSTR Msg)
{
CComCritSecLock<CComAutoCriticalSection> lock(m_CPMTCritSec);
ATL::CComVariant varResult;
int nConnections = m_Clients.GetSize();
int nConnectionIndex;
ATL::CComVariant* pvars = new ATL::CComVariant[1];
for (nConnectionIndex = 0; nConnectionIndex < nConnections; nConnectionIndex++)
{
ATL::CComPtr<IDispatch> sp;
if (SUCCEEDED(GetInterfaceAt(nConnectionIndex, sp)))
{
VariantClear(&varResult);
pvars[0] = Msg;
DISPPARAMS disp = { pvars, NULL, 1, 0 };
sp->Invoke(0x1, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, &disp, &varResult, NULL, NULL);
if (varResult.scode != S_OK)
{
// Do some error handling... (later)
return varResult.scode;
}
}
}
delete [] pvars;
return varResult.scode;
}
这个问题可能是这里提出的问题的重复: ATL COM:从其他线程访问事件方法 。 但是说句公道话,当我开始搜索时-我不知道搜索正确的单词。 谢谢。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.