问题描述
在 MSVC 中创建 ATL 项目似乎创建的不是一个而是两个项目;后者的名称与前者相同,但在其名称后附加了 PS.第二个项目的目的是什么,我怎么知道我是否需要它?
Creating an ATL project in MSVC seems to create not one but two projects; the latter named the same as the former but with PS appended to its name. What is the purpose of this second project and how can I tell whether I need it?
推荐答案
COM 支持跨两个不同的线程、两个不同的进程或两个不同的机器进行接口方法调用.这称为编组.两个不同的线程是最常见的情况,COM 服务器通常不是线程安全的.COM 通过将调用从错误"线程编组到创建服务器的线程来实现此类单线程协同类的线程安全.当您编写进程外服务器时,会在进程之间进行封送处理.跨网络的不同机器之间称为 DCOM.
COM supports making interface method calls across two different threads, two different processes or two different machines. This is called marshaling. Two different threads is the most common case, a COM server is often not thread-safe. COM implements thread-safety for such single-threaded coclasses by marshaling the call from the 'wrong' thread to the thread that created the server. Marshaling between processes occurs when you write an out-of-process server. Between different machines across a network is called DCOM.
这是通过创建一个看起来完全像原始界面的实例来实现的.但是接口的所有方法实际上都是完成调用编组工作的替代品.这是代理.在线路的另一端,有一个看起来完全像界面但做相反工作的替代品.这是存根.代理和存根协同工作,造成您在程序中进行简单方法调用的错觉.
This is implemented by creating an instance of the interface that looks exactly like the original. But all the methods of the interface are actually substitutes that do the job of the marshaling the call. This is the proxy. On the other end of the wire there's a substitute that looks exactly like the interface but does the opposite job. This is the stub. The proxy and stub work together to create the illusion that you're making a simple method call in your program.
代理的主要工作是将方法调用的参数序列化到内存缓冲区或网络数据包中.这可能非常重要,尤其是当您使用指向可变大小结构的指针时.COM 需要帮助才能做到这一点,这就是 FooPS 项目的工作.当您在 .idl 文件上运行 midl.exe 时,midl 会从接口定义自动生成代码以实现代理和存根.这通常已经足够了,但如果 IDL 中的内置关键字不足以描述您的数据,您可能需要实现自己的关键字.
The primary job of the proxy is to serialize the arguments of the method call into a memory buffer or network packet. This can be pretty untrivial, especially when you use pointers to variable-sized structures. COM needs help to get that right and that's the job of your FooPS project. When you run midl.exe on your .idl file, midl auto-generates code from the interface definitions to implement the proxy and the stub. This is quite often good enough but you may need to implement your own if the built-in keywords in IDL are not sufficient to describe your data.
最后但并非最不重要的一点是,Windows 提供了一个标准的编组器,可以编组简单的接口.旨在支持由 COM 自动化定义的 COM 子集.换句话说,派生自 IDispatch 且仅使用自动化兼容类型的接口.您只需要正确获取注册表项即可启用它,否则不需要 midl 生成的代理/存根.当然,如果您只在一个线程上进行简单的进程内调用,那么您也不需要它.这很常见.
Last but not least, Windows provides a standard marshaller that can marshal simple interfaces. Designed to support the sub-set of COM that's defined by COM Automation. In other words, interfaces that derive from IDispatch and only use Automation compatible types. You only need to get the registry entries right to enable it and don't otherwise need the proxy/stub generated by midl. And of course, if you only make simple in-process calls on one thread then you won't need it either. This is pretty common.
这篇关于我的 $Foo ATL 解决方案中的 ($Foo)PS 项目是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!