描述:
我在COM对象中建立了一个线程,当符合条件时,从该线程中激发事件(invoke),通过COM对象的外接口运行客户端的具体事件响应实现。因为采用的是STA模式,所以通过CoMarshalInterThreadInterfaceInStream在自建线程外进行列集,在线程函数中用CoGetInterfaceAndReleaseStream散集。经过我的测试,在外接口的函数中和在进入自建线程前检查Thread ID,二者是相同的,但仍然不能激发客户端的Invoke实现。迷惑不解ing。还请了解原因的朋友帮忙看一下。我是新人,分值不多,给分100,还请笑纳。下面是部分源码:
服务端
//
// TestServer.h : Declaration of the CTestServer
#ifndef __TESTSERVER_H_
#define __TESTSERVER_H_
#include "resource.h" // main symbols
#include "FireEventInSecondThread_ServerCP.h"
/////////////////////////////////////////////////////////////////////////////
// CTestServer
class ATL_NO_VTABLE CTestServer :
public CComObjectRootEx<CComSingleThreadModel>,
public CComCoClass<CTestServer, &CLSID_TestServer>,
public IConnectionPointContainerImpl<CTestServer>,
public IDispatchImpl<ITestServer, &IID_ITestServer, &LIBID_FIREEVENTINSECONDTHREAD_SERVERLib>,
public CProxy_ITestServerEvents< CTestServer >
{
public:
CTestServer()
{
m_pUnkMarshaler = NULL;
//
}
~CTestServer()
{
TerminateThread(m_hThread,0);
}
DECLARE_REGISTRY_RESOURCEID(IDR_TESTSERVER)
DECLARE_GET_CONTROLLING_UNKNOWN()
DECLARE_PROTECT_FINAL_CONSTRUCT()
BEGIN_COM_MAP(CTestServer)
COM_INTERFACE_ENTRY(ITestServer)
COM_INTERFACE_ENTRY(IDispatch)
COM_INTERFACE_ENTRY(IConnectionPointContainer)
COM_INTERFACE_ENTRY_AGGREGATE(IID_IMarshal, m_pUnkMarshaler.p)
COM_INTERFACE_ENTRY_IMPL(IConnectionPointContainer)
END_COM_MAP()
BEGIN_CONNECTION_POINT_MAP(CTestServer)
CONNECTION_POINT_ENTRY(DIID__ITestServerEvents)
END_CONNECTION_POINT_MAP()
HRESULT FinalConstruct()
{
char tmp[256] = {0};
sprintf(tmp,"ThreadID in Main is %0x",GetCurrentThreadId());
MessageBox(NULL,tmp,"",0);
ITestServer *pItest = 0;
QueryInterface(_GUID(IID_ITestServer),(void**)(&pItest));
CoMarshalInterThreadInterfaceInStream(IID_ITestServer,pItest,&m_pStm);
m_hThread = CreateThread(NULL,0,ThreadFunc,m_pStm,0,&m_nThreadID);
return CoCreateFreeThreadedMarshaler(
GetControllingUnknown(), &m_pUnkMarshaler.p);
}
void FinalRelease()
{
m_pUnkMarshaler.Release();
}
CComPtr<IUnknown> m_pUnkMarshaler;
// ITestServer
public:
STDMETHOD(DO)(/*[in]*/long param);
static DWORD WINAPI ThreadFunc(LPVOID);
void MyThreadFunc(long param);
HANDLE m_hThread;
unsigned long m_nThreadID;
IStream * m_pStm;
};
#endif //__TESTSERVER_H_
// TestServer.cpp : Implementation of CTestServer
#include "stdafx.h"
#include "FireEventInSecondThread_Server.h"
#include "TestServer.h"
/////////////////////////////////////////////////////////////////////////////
// CTestServer
DWORD WINAPI CTestServer::ThreadFunc(LPVOID pUser)
{
ITestServer *ITestserver;
static bEnterApartMent = FALSE;
if(!bEnterApartMent)
{
bEnterApartMent = TRUE;
CoInitialize(NULL);
}
CoGetInterfaceAndReleaseStream(LPSTREAM(pUser),IID_ITestServer,(void**)(&ITestserver));
static int i = 0;
while(1)
{
if(i >= 10)
break;
i++;
Sleep(3000);
ITestserver->DO(0);
}
ITestserver->Release();
if(bEnterApartMent)
CoUninitialize();
return 0;
}
void CTestServer::MyThreadFunc(long param)
{
}
STDMETHODIMP CTestServer::DO(long param)
{
// TODO: Add your implementation code here
Fire_Fire(0);
return S_OK;
}
解决方案1:
ITestServer *pItest = 0;
QueryInterface(_GUID(IID_ITestServer),(void**)(&pItest));这里是否成功?pitem是否有值
CoMarshalInterThreadInterfaceInStream(IID_ITestServer,pItest,&m_pStm);//m_pstm是否有值
CoGetInterfaceAndReleaseStream(LPSTREAM(pUser),IID_ITestServer,(void**)(&ITestserver));
ITestserver这里是否成功获得?