• linkedu视频
  • 平面设计
  • 电脑入门
  • 操作系统
  • 办公应用
  • 电脑硬件
  • 动画设计
  • 3D设计
  • 网页设计
  • CAD设计
  • 影音处理
  • 数据库
  • 程序设计
  • 认证考试
  • 信息管理
  • 信息安全
菜单
linkedu.com
  • 网页制作
  • 数据库
  • 程序设计
  • 操作系统
  • CMS教程
  • 游戏攻略
  • 脚本语言
  • 平面设计
  • 软件教程
  • 网络安全
  • 电脑知识
  • 服务器
  • 视频教程
  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号
您的位置:首页 > 程序设计 >vc/mfc > 一个关于COM线程模型的问题

一个关于COM线程模型的问题

作者:佚名 字体:[增加 减小] 来源:互联网 时间:2017-06-04

佚名通过本文主要向大家介绍了 一个关于COM线程模型的问题等相关知识,希望对您有所帮助,也希望大家支持linkedu.com www.linkedu.com
问题: 一个关于COM线程模型的问题
描述:

现在我有一个DLL形式的COM组件,是一个Apartment-Thread模型的组件。现在我在一个Worker线程中调用这个COM。按照《COM的原理与应用》里面说得,worker线程相对于COM机制中的Multi-Thread模型,所以COM库会另外生成一个UI线程来容纳这个COM组件,而那个Worker线程要用proxy-stub机制来访问这个COM组件。但是这样岂不是效率太低了,如果我只有这一个worker线程访问COM组件,根本不会造成COM组件的访问冲突,也要这样来实现吗?
谢谢!!


解决方案1:

调用CoInitializeEx指定ApartmentThread可以进入STA,但调用线程必须要有自己的消息循环,否则Apartment-Thread模型的组件就会没有响应

解决方案2:

选择STA还是MTA主要取决于你实现的组件是否线程安全。

解决方案3:

你如果只有这一个worker线程访问COM组件,可以让线程进入STA就行了,为什么要进入MTA?

解决方案4:

跨越套间访问的两种规则:汇集和全局接口表
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.

解决方案5:

你加个消息循环不就行了,不就是两三句话吗?


分享到:QQ空间新浪微博腾讯微博微信百度贴吧QQ好友复制网址打印

您可能想查找下面的文章:

相关文章

  • 2017-06-04 如何在对话框中嵌入excel
  • 2017-06-04 建立一个EXE形式的COM组件后为什么运行一段时间后没有任何操作的情况下会自动销毁呢?
  • 2017-06-04 GIS_COM
  • 2017-06-05 请教高手!关于钩子程序如何控制指定窗口的问题。
  • 2017-06-04 关于从ie上下载ocx的问题,请高手帮忙。
  • 2017-06-05 MFC写的MSCOMM控件问题
  • 2017-06-05 Vc实现的非模态对话框在VC6下加载按钮都不让点
  • 2017-06-05 100分的问题,急!!!(关于多线程)
  • 2017-06-04 ULONG如何转换成BSTR或者VARIANT?
  • 2017-06-04 active控件如何获得post过来在数据?

文章分类

  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号

最近更新的内容

    • 特急,重分,有没有人用过CJ60Lib(就是仿VC界面)这个第三方控件?其有没有资源泄露的问题?或其他问题?
    • 急问???谁能给我提供处理硬件中断的控件???如:tvichw32ocx等,处理硬件中断的API方法也可以!!!多谢了!!!
    • 一个很怪的问题
    • isapi添加数据库支持的问题
    • 关于程序控制的问题,如何受控的启动一个可执行文件,从而达到对此程序的License管理,很急,大家进来帮帮我吧
    • 关于容器的问题
    • 请问一个关于IConnectionPointContainer实现的问题
    • 如何设置word/excel/powerpoint的显示比例
    • 用vc写了一个提取wma文件信息的ocx控件在asp调用中的ErrorType:0x8000FFFFCatastrophicfailure??
    • 有关在com中截取所在网页事件的问题!

关于我们 - 联系我们 - 免责声明 - 网站地图

©2020-2025 All Rights Reserved. linkedu.com 版权所有