现在我有一个DLL形式的COM组件,是一个Apartment-Thread模型的组件。现在我在一个Worker线程中调用这个COM。按照《COM的原理与应用》里面说得,worker线程相对于COM机制中的Multi-Thread模型,所以COM库会另外生成一个UI线程来容纳这个COM组件,而那个Worker线程要用proxy-stub机制来访问这个COM组件。但是这样岂不是效率太低了,如果我只有这一个worker线程访问COM组件,根本不会造成COM组件的访问冲突,也要这样来实现吗?谢谢!!
解决方案 »
- 请教error C2664: 'wcslen' 问题
- CoCreateInstanc失败,GetLastError返回值为14007,这个问题该怎么解决,该去注册哪个动态库?
- CreateSoundBuffer失败返回E_INVALIDARG 会是什原因?
- 如何锁住一个文件夹
- IMediaSeeking接口在哪些filter graph中可用?
- 请问一下怎么在按钮的左边显示一个图标,右边显示文字呢?我这里总是只显示图标在中间,文字就不见了。
- 如何在VC中播放声音文件?
- 问一个问题,可能比较弱智,大家帮忙看看
- 灰度图像像素值
- 如何指定用IE(不是缺省浏览器)在同一窗口打开链接,不打开新的窗口
- 这是我的函数,大家看有问题吗!
- 问一个菜鸟问题!
To make an interface pointer available to all apartments in the process, the apartment that owns the interface pointer must register it with the GIT by calling the RegisterInterfaceInGlobal method. The GIT will return a DWORD to the caller that represents the pointer globally across all apartments in the process. This DWORD can be used from any apartment in the process to unmarshal a new proxy by calling the GetInterfaceFromGlobal method. This DWORD can be used to unmarshal proxies repeatedly until a call to RevokeInterfaceFromGlobal invalidates the global interface pointer. Applications that use the global interface table usually bind a single process-wide interface pointer at startup:IGlobalInterfaceTable *g_pGIT = 0;
HRESULT InitOnce(void) {
assert(g_pGIT == 0);
return CoCreateInstance(CLSID_StdGlobalInterfaceTable, 0,
CLSCTX_INPROC_SERVER,
IID_IGlobalInterfaceTable,
(void**)&g_pGIT);
}
Once the global interface table is available, passing an interface pointer to another apartment simply means registering the pointer with the global interface table:HRESULT WritePtrToGlobalVariable(IRacer *pRacer) {
// where to write the marshaled ptr
extern DWORD g_dwCookie;
// thread synchronization
extern HANDLE g_heventWritten;
// write marshaled object reference to global variable
HRESULT hr = g_pGIT->RegisterInterfaceInGlobal(
IID_IRacer, pRacer, &g_dwCookie);
// signal other thread that ptr is now available
SetEvent(g_heventWritten);
return hr;
}
The following code correctly unmarshals the object reference and can be called from any apartment in the same process:HRESULT ReadPtrFromGlobalVariable(IRacer * &rpRacer,
bool bLastUnmarshal) {
// where to write the marshaled ptr
extern DWORD g_dwCookie;
// thread synchronization
extern HANDLE g_heventWritten;
// wait for other thread to signal that ptr is available
WaitForSingleObject(g_heventWritten, INFINITE);
// read marshaled object reference from global variable
HRESULT hr = g_pGIT->GetInterfaceFromGlobal(
g_dwCookie, IID_IRacer, (void**)&rpRacer);
// if we are the last to unmarshal, revoke the pointer
if (bLastUnmarshal)
g_pGIT->RevokeInterfaceFromGlobal(g_dwCookie);
return hr;
}
Note that a critical difference between these code fragments and the examples using CoMarshalInterThreadInterfaceInStream is that the GIT-based code supports unmarshaling more than one proxy.7 It may seem odd that the global variable is an interface pointer that is initialized in the writer’s apartment and used from the reader’s apartment. This inconsistency is addressed by the documentation for CoMarshalInterThreadInterfaceInStream, which states that the resultant IStream interface pointer can be accessed from any apartment in the process.
是ApartmentThread,就可以进入STA?我一直以为要进入STA,线程一定要有自己的消息
循环。to zylstudy:我得组件是线程不安全的,但是我现在要在一个Worker线程中调用它。
消息循环,我如何退出呢?