_MERGE_PROXYSTUB有什么意义?

时间:2009-09-18 12:54:52

标签: c++ com atl

我使用VS2008生成了一个ATL COM对象,代码包含对名为_MERGE_PROXYSTUB的定义的引用(因为我在最初运行向导时选择了'Merge proxy / stub'选项。)

代理/存根有什么意义?如果我没有选择合并选项,那么我会得到一个单独的MyControlPS.DLL - 何时会被使用?

如果我删除_MERGE_PROXYSTUB定义所包围的所有代码,则控件似乎注册并正常工作。调试版本甚至没有定义_MERGE_PROXYSTUB,它仍然可以正常工作。

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

2 个答案:

答案 0 :(得分:15)

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

例如,我们有一个插件,由使用特定线程模型的应用程序(无法记住哪个)加载,但我们的COM对象是多线程单元(MTA) - 因此需要代理/存根在进行函数调用时对数据之间的数据进行编组,同时仍然遵守线程模型的规则。

如果这些规则被破坏,那么COM将抛出异常或返回失败的HRESULT,例如 RPC_E_WRONG_THREAD

如果不检查合并代理/存根选项,则visual studio会为代理/存根生成一个单独的项目,该项目将构建到单独的dll中。如果需要,这会使部署更加困难,但如果您不受线程模型问题的影响,基本上可以忽略它们。

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

Larry Osterman在他的博客上提供了threading models的可读介绍。

答案 1 :(得分:3)

此外,如果您的接口只包含类型库友好类型(BSTR,VARIANT等)并出现在IDL的库块中,您可以选择让它们“类型库编组”,这意味着系统提供proxy / stub使用类型库中的元数据。

当接口放入库块中,并且DllRegisterServer被自定义以注册类型库(如果我没记错的话,将TRUE传递给XxxModule :: DllRegisterServer),系统将根据需要对接口进行编组,如下所述: John Sibly。

此时,甚至没有使用代理/存根,因此_MERGE_PROXYSTUB无效。