COM支持在两个不同的线程、两个不同的进程或两个不同的机器之间进行接口方法调用。 这被称为封送。其中,两个不同的线程是最常见的情况,因为COM服务器通常不是线程安全的。对于这样的单线程coclass,COM通过将调用从“错误”的线程封送到创建服务器的线程来实现线程安全性。当您编写一个独立进程的服务器时,会发生进程间封送。跨网络连接的不同计算机之间的封送称为DCOM。
这是通过创建一个与原始接口完全相同的接口实例来实现的。但是,接口的所有方法实际上都是代替品,它们执行封送调用的工作。这是代理。在另一端的线路上有一个看起来完全相同的代替品,但却执行相反的工作。这是存根。代理和存根共同工作,创造了一个假象,使您的程序似乎正在进行简单的方法调用。
代理的主要任务是将方法调用的参数序列化为内存缓冲区或网络数据包。这可能非常复杂,特别是当您使用指向可变大小结构的指针时。COM需要帮助才能做到这一点,这就是您的FooPS项目的工作。当您在.idl文件上运行midl.exe时,midl会从接口定义中自动生成代码以实现代理和存根。这通常已经足够好了,但如果IDL中内置的关键字不足以描述您的数据,则可能需要自己实现。
最后,Windows提供了一个标准的封送程序,可以封送简单的接口。它被设计用于支持由COM自动化定义的COM子集。换句话说,它适用于继承自IDispatch并且仅使用自动化兼容类型的接口。只需正确设置注册表条目即可启用它,并且不需要midl生成的代理/存根。当然,如果您仅在一个线程上进行简单的进程内调用,则也不需要它。这是非常常见的。
这是代理/存根代码,其中包含传输不同公寓(与线程相关)之间的数据所需的非标准数据编组器。当调用您的COM对象的应用程序使用不同的COM线程模型时,它被使用。在ATL/COM向导中有一个选项可以将此代码合并到主库中。在许多常见情况下,您无需担心它(即当您的COM dll在客户端上下文中运行时),除非您想编写自定义编组器。