一个COM异步实现接口列集(Marshal)源代码实例
2005-07-27 13:32
435 查看
在COM中实现异步是非常复杂但又非常有用的。Process如下:
1. 列集要在线程里使用的接口。
2. Create一个线程。
3. 在线程里Release列集。
4. 调用接口的方法。
头文件如下:
class ATL_NO_VTABLE CAsync
{
protected:
CAsync();
virtual ~CAsync();
private:
unsigned int RunThread();
static unsigned int __stdcall ThreadFunction(void *pFun); //线程函数
HANDLE m_hThread;
protected:
STDMETHOD(EnableAsyncFunction)( IUnknown *pUnkSink); //异步的方法,传入需要列集的接口
/////////////////////////////////////////////////////////////////////
IStream *m_pIStream;
};
源文件如下:
STDMETHODIMP CAsync::EnableAsyncFunction( IUnknown *pUnkSink)
{
HRESULT hr = S_OK;
_AsyncNeedMarshal *m_pIHelper=0;
hr = pUnkSink->QueryInterface(IID__NEED, (void**)&m_pIHelper);
if (SUCCEEDED(hr))
{
//列集m_pIHelper
if( FAILED( ::CoMarshalInterThreadInterfaceInStream(IID__AsyncNeedMarshal,m_pIHelper, &m_pIStream)) )
{
return S_FALSE;
}
m_pIHelper->Release();
}
if (SUCCEEDED(hr))
{
DWORD threadID = 0;
//起线程
m_hThread =CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)ThreadFunction, this, 0, &threadID);
if (0 == m_hThread)
{
hr = E_FAIL;
m_hThread = INVALID_HANDLE_VALUE;
}
}
return hr;
}
unsigned int __stdcall CAsync::ThreadFunction(void *pFun)
{
unsigned int result = 0;
if (pFun)
{
::CoInitialize(0);
//线程函数调用RunThread()方法,真正的运行内容在RunThread()内。
CAsyncMessageReceive &me = *(CAsyncMessageReceive*)pFun;
result = me.RunThread();
::CoUninitialize();
}
return result;
}
unsigned int CAsync::RunThread()
{
_AsyncNeedMarshal *m_pIHelper=0;
//反列集,注意抛出异常的原因有:列集的接口没有在注册表里注册。
HRESULT hr = ::CoGetInterfaceAndReleaseStream(m_pIStream, IID__AsyncNeedMarshal, (void**)&m_pIHelper );
//得到接口对象指针,可以调用该对象的方法了。
m_pIHelper ->Function();
if (m_pIHelper!=NULL)
{
m_pIHelper->Release();
m_pIHelper= 0;
}
return 0;
}
1. 列集要在线程里使用的接口。
2. Create一个线程。
3. 在线程里Release列集。
4. 调用接口的方法。
头文件如下:
class ATL_NO_VTABLE CAsync
{
protected:
CAsync();
virtual ~CAsync();
private:
unsigned int RunThread();
static unsigned int __stdcall ThreadFunction(void *pFun); //线程函数
HANDLE m_hThread;
protected:
STDMETHOD(EnableAsyncFunction)( IUnknown *pUnkSink); //异步的方法,传入需要列集的接口
/////////////////////////////////////////////////////////////////////
IStream *m_pIStream;
};
源文件如下:
STDMETHODIMP CAsync::EnableAsyncFunction( IUnknown *pUnkSink)
{
HRESULT hr = S_OK;
_AsyncNeedMarshal *m_pIHelper=0;
hr = pUnkSink->QueryInterface(IID__NEED, (void**)&m_pIHelper);
if (SUCCEEDED(hr))
{
//列集m_pIHelper
if( FAILED( ::CoMarshalInterThreadInterfaceInStream(IID__AsyncNeedMarshal,m_pIHelper, &m_pIStream)) )
{
return S_FALSE;
}
m_pIHelper->Release();
}
if (SUCCEEDED(hr))
{
DWORD threadID = 0;
//起线程
m_hThread =CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)ThreadFunction, this, 0, &threadID);
if (0 == m_hThread)
{
hr = E_FAIL;
m_hThread = INVALID_HANDLE_VALUE;
}
}
return hr;
}
unsigned int __stdcall CAsync::ThreadFunction(void *pFun)
{
unsigned int result = 0;
if (pFun)
{
::CoInitialize(0);
//线程函数调用RunThread()方法,真正的运行内容在RunThread()内。
CAsyncMessageReceive &me = *(CAsyncMessageReceive*)pFun;
result = me.RunThread();
::CoUninitialize();
}
return result;
}
unsigned int CAsync::RunThread()
{
_AsyncNeedMarshal *m_pIHelper=0;
//反列集,注意抛出异常的原因有:列集的接口没有在注册表里注册。
HRESULT hr = ::CoGetInterfaceAndReleaseStream(m_pIStream, IID__AsyncNeedMarshal, (void**)&m_pIHelper );
//得到接口对象指针,可以调用该对象的方法了。
m_pIHelper ->Function();
if (m_pIHelper!=NULL)
{
m_pIHelper->Release();
m_pIHelper= 0;
}
return 0;
}
相关文章推荐
- lesson 8: 编写一个Book类,该类至少有name和price两个属性。该类要实现Comparable接口,在接口的compareTo()方法中规定两个Book类实例的大小关系为二者的pric
- java中请给一个Abstract类实现接口的实例!
- ruby实现的一个异步文件下载HttpServer实例
- (1)定义一个接口Compute含有一个方法int computer(int n,int m); (2)设计四个类分别实现此接口,完成+-*/运算 (3)设计一个类UseCompute,含有方法: public void useCom(Compute com, int one, int two) (4)设计一个测试类
- 使用Promise和async-await实现的一个异步遍历+同步执行任务的实例
- 实例化一个子类对象赋给父类对象引用或一个实现了接口的类的对象赋给接口的引用的好处
- 编写一个Book类,该类至少有name和price两个属性。该类要实现Comparable接口,在接口的compareTo()方法中规定两个Book类实例的大小关系为二者的price属性的大小关系。在
- 实现了Runnable接口的实例,就一定会启动一个新的线程么?
- 简单工厂(Factory)-提供一个创建对象实例的功能,而无须关心其具体实现。被创建实例的类型可以是接口、抽象类,也可以是具体的类。
- 1 编写一个Book类,该类至少有name和price两个属性。该类要实现Comarable接口,在接口的compareTo()方法中规定两个Book类实例的大小关系为二者的price属性的大小关系。
- COM 接口得到实现该接口的对象实例
- NodeJS用递归实现异步操作的链式调用,完成一个简易的命令行输入输出REPL交互接口
- J2ME应用实例——一个简单的计算器实现(附源代码)
- 如何判断一个实例或者一个类实现某接口呢?
- 读写锁接口实例-通过ReadWriteLock实现一个简单的缓存
- [C#]实现IEnumerable接口来使用foreach语句的一个实例
- J2ME应用实例——一个简单的计算器实现(附源代码)
- 编写一个Book类,该类至少有name和price两个属性。该类要实现Comparable接口,在接口的compareTo()方法中规定两个Book类实例的大小关系为二者的price属性的大小关系。在
- 编写一个Book类,该类至少有name和price两个属性。该类要实现Comparable接口,在接口的compareTo()方法中规定两个Book类实例的大小关系为二者的price属性的大小关系。在
- 编写一个Book类,该类至少有name和price两个属性。该类要实现Comarable接口,在接口的compareTo()方法中规定两个Book类实例的大小关系为二者的price属性的大小关系。