_MERGE_PROXYSTUB 有啥意义?
Posted
技术标签:
【中文标题】_MERGE_PROXYSTUB 有啥意义?【英文标题】:What's the point of _MERGE_PROXYSTUB?_MERGE_PROXYSTUB 有什么意义? 【发布时间】:2010-11-29 11:39:47 【问题描述】:我使用 VS2008 生成了一个 ATL COM 对象,代码包含对名为 _MERGE_PROXYSTUB
的定义的引用(因为我在最初运行向导时选择了“合并代理/存根”选项。)
代理/存根有什么意义?如果我不选择合并选项,那么我会得到一个单独的 MyControlPS.DLL
- 什么时候会使用它?
如果我删除由_MERGE_PROXYSTUB
定义的所有代码,则该控件似乎已注册并正常工作。调试版本甚至没有定义_MERGE_PROXYSTUB
,它仍然可以正常工作。
那么,我可以不用代理/存根吗?
【问题讨论】:
【参考方案1】:如果您希望使用与 COM 对象不同的线程模型从应用程序调用您的 COM 对象,则需要代理/存根。
例如,我们有一个由使用特定线程模型(不记得是哪个)的应用程序加载的插件,但我们的 COM 对象是多线程单元 (MTA) - 所以需要代理/存根在进行函数调用时编组对象之间的数据,同时仍遵守线程模型的规则。
如果这些规则被破坏,那么 COM 要么抛出异常,要么返回失败 HRESULT,例如 RPC_E_WRONG_THREAD
如果您不选中合并代理/存根选项,则 Visual Studio 会为代理/存根生成一个单独的项目,该项目将构建到单独的 dll 中。如果需要,这会使部署变得更加困难,但如果您不受线程模型问题的影响,您基本上可以忽略它们。
因此,如果调用 COM 对象的应用程序使用与您的对象相同的线程模型,那么您可以不使用代理/存根
Larry Osterman 在他的博客上提供了对threading models 的可读介绍。
【讨论】:
【参考方案2】:此外,如果您的接口仅包含类型库友好类型(BSTR、VARIANT 等)并出现在 IDL 的库块中,您可以选择让它们“编组类型库”,这意味着系统提供proxy/stub 使用类型库中的元数据。
当接口被放入库块中,并且 DllRegisterServer 被定制为注册类型库(如果我没记错的话,将 TRUE 传递给 XxxModule::DllRegisterServer)你的接口将在必要时由系统编组,如约翰·西布利。
此时,甚至没有使用代理/存根,所以_MERGE_PROXYSTUB
没有任何作用。
【讨论】:
以上是关于_MERGE_PROXYSTUB 有啥意义?的主要内容,如果未能解决你的问题,请参考以下文章