我的$ Foo ATL解决方案中的($ Foo)PS项目是什么?

问题描述 投票:23回答:3

在MSVC中创建一个ATL项目似乎创建了一个而不是两个项目;后者的名称与前者相同,但附加了PS名称。第二个项目的目的是什么?如何判断我是否需要它?

c++ visual-studio com atl
3个回答
35
投票

COM支持跨两个不同的线程,两个不同的进程或两个不同的机器进行接口方法调用。这称为编组。两种不同的线程是最常见的情况,COM服务器通常不是线程安全的。 COM通过将来自“错误”线程的调用封送到创建服务器的线程来实现此类单线程coclass的线程安全性。当您编写进程外服务器时,会在进程之间进行封送处理。在网络上的不同机器之间称为DCOM。

这是通过创建看起来与原始接口完全相同的接口实例来实现的。但是接口的所有方法实际上都是替代方法,可以完成编组调用的工作。这是代理。在电线的另一端有一个看起来与接口完全相同的替代品,但做了相反的工作。这是存根。代理和存根一起工作以创建您在程序中进行简单方法调用的错觉。

代理的主要工作是将方法调用的参数序列化为内存缓冲区或网络数据包。这可能非常重要,特别是当您使用指向可变大小结构的指针时。 COM需要帮助才能做到这一点,这是你的FooPS项目的工作。在.idl文件上运行midl.exe时,midl会自动生成接口定义中的代码以实现代理和存根。这通常很好,但如果midl中的内置关键字不足以描述您的数据,则可能需要实现自己的。

最后但同样重要的是,Windows提供了一个标准的编组器,可以编组简单的接口。旨在支持COM自动化定义的COM子集。换句话说,从IDispatch派生的接口仅使用与Automation兼容的类型。您只需要使用正确的注册表项来启用它,否则不需要midl生成的代理/存根。当然,如果你只在一个线程上进行简单的进程内调用,那么你也不需要它。这很常见。


8
投票

正如@ebutusov所说,* PS项目包含Proxy and Stub的实现。它们不是标准的,而是由MIDL为从ATL服务器导出的接口生成的。这些接口在* .IDL文件中声明。该项目的输出是DLL。您可以阅读this article以获取更多详细信息。

如果您没有在* .IDL文件中定义任何自定义接口,或者只定义具有dual和oleautomation修饰符的接口,则可以从解决方案中删除PS项目。在这种情况下,将使用标准的typelib marshaller。

为了能够使用标准的typelib marshaller,必须注册一个类型库(由于你使用的是ATL,它会自动完成)


5
投票

它是代理/存根代码,包含在不同公寓之间传输数据所需的非标准数据编组器(与线程相关)。当调用COM对象的应用程序使用不同的COM线程模型时使用它。 ATL / COM向导中有一个选项可将此代码合并到主库中。在许多常见的场景中,您不必担心它(即当您的COM dll在客户端上下文中运行时),除非您想编写自定义编组程序。

© www.soinside.com 2019 - 2024. All rights reserved.