问了无数遍了,还是没理解透彻:(coclass CA实现了IA接口,IA接口有两个方法IA_Method1,IA_Method2。同时CA有一个辅助函数CA_Method1。
在CA类中有一成员IB *pIB,是在CA的FinalConstruct中创建的,创建成功后将其放置到了GIT中,cookie保存在m_dwCookie中。GIT指针保存在一个全局智能指针变量中:CComPtr<IGlobalInterfaceTable> g_spGIT = NULL;CA::IA_Method1实现如下:
CreateThread(NULL,0,threadProc,this,0,NULL);
即将CA的this指针传递到了工作线程中。工作线程中使用的是强制转换:
ulong CA::threadProc(LPVOID pVoid)
{
CA *pCA = (CA *)pVoid;
return pCA->realProc();
}然后在realProc中通过m_dwCookie获取到IB指针并调用IB接口的方法。同时在readProc中还需要调用IA_Method2和CA_Method1。不知道这样实现会不会有问题(也不知道表达清楚了没有)?还有,这跟CA是进程内组件或进程外组件有关系吗?
在CA类中有一成员IB *pIB,是在CA的FinalConstruct中创建的,创建成功后将其放置到了GIT中,cookie保存在m_dwCookie中。GIT指针保存在一个全局智能指针变量中:CComPtr<IGlobalInterfaceTable> g_spGIT = NULL;CA::IA_Method1实现如下:
CreateThread(NULL,0,threadProc,this,0,NULL);
即将CA的this指针传递到了工作线程中。工作线程中使用的是强制转换:
ulong CA::threadProc(LPVOID pVoid)
{
CA *pCA = (CA *)pVoid;
return pCA->realProc();
}然后在realProc中通过m_dwCookie获取到IB指针并调用IB接口的方法。同时在readProc中还需要调用IA_Method2和CA_Method1。不知道这样实现会不会有问题(也不知道表达清楚了没有)?还有,这跟CA是进程内组件或进程外组件有关系吗?
解决方案 »
- 用delphi开发的项目多吗
- vc++6.0中有UpDateData(FALSE).vc++2005中有吗?如果没有,相同用法的函数是什么?我在msdn2005 中查不到UpDateData函数
- VC++.net中UML逆向工程
- C++的消息机制
- 我用mfc编写了一个ocx控件,为什么在网页中显示不了?
- ATL的简单问题。
- 关于控件的制作!!
- 哪位大侠能告诉我网络抓包工具是如何实现的?放分
- 无法从“long (__thiscall CCmdTest::* )(WPARAM,LPARAM)”转换为“LRESULT (__thiscall CWnd::* )(WPARAM,LPARAM)
- 简单问题
- 如何获取选择项目的文本
- 一个关于VC++MFC对话框的问题
我想确认的就是我在realProc(工作线程中执行)函数中通过强制转换得到的CA指针来调用CA的辅助函数和IA接口函数会不会有问题?而这个IA接口不是通过列集散集得到的。
也就是说下面这个函数的实现本身就是有问题的,对吗?
ulong CA::threadProc(LPVOID pVoid)
{
CA *pCA = (CA *)pVoid;
return pCA->realProc();
}
如果这个实现有问题,那么调用IA_Method2还可以通过将IA接口指针放到GIT中来解决,但如何才能调用到CA_Method1呢?
CA_Method1函数里还要用到一些CA的类变量,也不想把这个函数从IA接口中导出,那么在工作线程中应该如何才能调用到CA::CA_Method1呢?
有没有简单一点点的方法呢?因为不光是CA_Method1,还有CA_Method2,CA_Method3...
另外,既然不要在接口映射表中添加IC的查询映射,那么是否是直接通过static_cast转换一个IC的指针存在GIT中?
还有一个问题,GIT的指针是一个全局指针,没有通过列集散集在工作线程中直接使用,会不会存在问题?谢谢!谢谢!谢谢!谢谢!谢谢!谢谢!谢谢!谢谢!
如果CA的类方法是被IC来调用的,那么CA_Method1里面可以随意调用IA_Method2或者其它方法,因为它们的线程上下文是相同的。
coclass CA实现了IA接口,IA接口有两个方法IA_Method1,IA_Method2。
CA有一个辅助函数CA_Method1以及一个成员变量int m_nX;
同时,CA类中还有一成员变量IB *pIB,是在CA的FinalConstruct中进行CreateInstance。IB有一个接口函数IB_Method1。CA::IA_Method1是一个耗时非常长的操作,所以使用了工作线程。在工作线程的线程函数体中需要调用到IA_Method2、IB_Method1、CA_Method1以及CA::m_nX。我的结论是:
不管CA是套间线程模型还是自由线程模型,都必须对IA和IB接口进行列集散集或保存到GIT以供工作线程使用。对于CA::m_nX来说,必须使用一个不公开的接口例如IC,CA实现IC,同时将IC接口也进行列集散集或通过GIT传递到工作线程,在工作线程中再通过IC::get_X和IC::put_X来访问CA::m_nX。请教浆糊老师,上述结论中有没有哪个步骤是可以省略的(或者说有没有哪句话是不必要的)?严重感谢,加分以示谢意!
跨线程使用自由线程组件,可以直接传递接口指针,没有列集过程,也可以CAST,唯一需要关注的就是CA内部数据的同步。
以下是我的实际测试结果,很是头痛:(以下结论适用于进程内组件也适用于进程外组件,适用于套间线程模型也适用于自由线程模型。进程内组件的载体为CA.DLL,进程外组件的载体为CA.EXE。
CA组件实现了IA接口
IA接口有一个方法名为m1
CA类有一个成员变量int m_nX,在CA的构造中m_nX值被设置为12345
CA类有一个辅助函数m2(不属于IA接口的方法),m2的实现是弹出一个MessageBoxm1的实现如下:
STDMETHODIMP CA::m1()
{
CreateThread(NULL,0,threadProc,this,0,NULL);
return S_OK;
}threadProc的实现如下:
unsigned long CA::threadProc(LPVOID pVoid)
{
CA *pC = (CA*)pVoid; wchar_t buffer[100];
swprintf(buffer,L"[%d] : %d",GetCurrentThreadId(),pC->m_nX);
MessageBoxW(NULL,buffer,L"Info",MB_ICONINFORMATION); pC->m2();
return 0;
}
测试流程如下:在测试程序的主对话框类中添加一个成员变量IA *pA。
在OnInitDialog函数中对pA进行CreateInstance,并调用其m1函数。可以看到输出的m_nX值是正确的12345,m2函数的调用也是正确的。而且弹出的MessageBox所在的线程是位于CA.DLL(CA.EXE)中的。在测试程序的OnOK中添加如下代码:
void CTestfdsDlg::OnOK()
{
IStream *pStream;
CoMarshalInterThreadInterfaceInStream(IID_IA,static_cast<IUnknown*>(pA),&pStream);
CreateThread(NULL,0,threadProc,pStream,0,NULL);
}threadProc实现如下:
unsigned long CTestfdsDlg::threadProc(LPVOID pVoid)
{
CoInitialize(NULL); //此处换作CoInitializeEx(NULL,COINIT_MULTITHREADED);测试结果亦一样。 IStream *pStream = static_cast<IStream*>(pVoid);
IA *iht;
if(FAILED(CoGetInterfaceAndReleaseStream(pStream,IID_IA,(void**)&iht)))
{
::MessageBox(NULL,"CoGetInterfaceAndReleaseStream failed","Error",MB_ICONINFORMATION); CoUninitialize();
return -1;
} iht->m1();
iht->Release(); CoUninitialize();
return 0;
}
可以看到输出的m_nX值是正确的12345,m2函数的调用也是正确的。而且弹出的MessageBox所在的线程是位于CA.DLL(CA.EXE)中的。
结论是:在实现某个接口方法时,可以将接口实现类的this指针传入到工作线程,在工作线程中可以调用到接口实现类的辅助函数和成员变量等,没有问题。
没有经过权威的论证,只测试过进程内组件和进程外组件,没有测试过远程组件(因为不知道怎么测)
--
不管你的测试工程是否正确,我可以肯定的告诉你,你在test中的理解是错的。
事实上我是在实际使用过程中使用了test中的结论,而且这个实际应用远比test复杂,如下图所示:
经过vc,vb,javascript调用都没有出现问题,所以才又做了一个test工程来进行专门的测试。
是啊,我也在想将经过代理得到的IA指针转换为CA会出错,所以才做了个test工程来测试。
但是结果出乎我的意料啊,就算CA是进程外组件,然后我在主线程中创建然后列集到工作线程中再散集得到IA指针,然后再调用此指针的IA_Method1,也没有出现问题。
这个IA接口肯定是经过代理的。
从理论上来说,你就算不用列集,直接传递给线程 ,从理论上来说,应该是指向的同一个对象,但是
套件是不充许的,显然是有什么地方是限制了的,只是我们不知道。如果你想证明的话,你应该做一个远程 调用看看,就是DCOM,那肯定就是代理,你再试试看。