_MERGE_PROXYSTUB有什么作用?

13

我使用VS2008生成了一个ATL COM对象,代码中包含一个名为_MERGE_PROXYSTUB的定义(因为我最初运行向导时选择了“合并代理/存根”选项)。

代理/存根有什么用?如果我不选择合并选项,那么我会得到一个单独的MyControlPS.DLL - 什么情况下会使用它?

值得注意的是,如果我删除所有由_MERGE_PROXYSTUB定义包围的代码,则该控件似乎可以注册和正常工作。调试版本甚至没有定义_MERGE_PROXYSTUB也能够正常工作。

那么,我可以不使用代理/存根吗?

2个回答

18

如果您希望在使用不同线程模型的应用程序中调用您的COM对象,则需要使用代理/存根。

例如,我们有一个插件被加载到使用特定线程模型(无法记住哪个)的应用程序中,但我们的COM对象是多线程公寓(MTA) - 因此在进行函数调用时需要代理/存根来在对象之间传递数据,同时仍要遵循线程模型的规则。

如果违反这些规则,则COM将抛出异常或返回失败的HRESULT,如RPC_E_WRONG_THREAD

如果您没有检查合并代理/存根选项,则Visual Studio会为代理/存根生成单独的项目,这些项目会构建成单独的dll。如果需要它们,这会使部署变得更加困难,但是如果您没有受线程模型问题影响,那么基本上可以忽略它们。

因此,如果调用COM对象的应用程序正在使用与您的对象相同的线程模型,则可以不使用代理/存根。

Larry Osterman在他的博客上提供了易于理解的线程模型介绍


1
谢谢@Sabuncu - 我已经更新了链接。 - John Sibly
1
谢谢,这是一个有价值的答案,我想确认它是最新的。 - Sabuncu

5
此外,如果您的接口仅包含类型库友好的类型(BSTR、VARIANT等),并且出现在IDL的库块中,您可以选择将它们“类型库封送”,这意味着系统提供的代理/存根使用类型库中的元数据。
当接口放置在库块内,并且自定义DllRegisterServer以注册类型库(如果我记得正确,则将TRUE传递给XxxModule :: DllRegisterServer),如果需要,系统将封送您的接口,如John Sibly所描述。
此时,代理/存根甚至都没有被使用,因此_MERGE_PROXYSTUB没有任何效果。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接