跨另一个进程共享进程内 COM 对象
在我问这个问题之前,我想明确表示我知道有用于进程间通信的库和技术.不过,这是一个关于 COM 的学习问题.我也知道进程外服务器,但这不是我想要的.
Before I ask this question I would like to make it clear that I know there are libraries and techniques for Inter process communcation. This though, is a learning question about COM. I also do know about out-of-proc servers but that's not what I am looking for.
问题:
我想知道,因为我不知道,是否有可能,如果是的话,如何共享一个进程中的进程内 COM 对象(在 DLL 中定义的对象)(已在进程)跨越另一个进程?即,如何从进程 B 中的进程 A 获取指向进程内对象的指针?
What I want to know, because I don't know this, is it possible, and if yes how, to share an in-proc COM object (object defined in a DLL) living in one process (has been instantiated in the process) across another process? Ie, how do I obtain a pointer to the in-proc object from proces A in process B?
提前致谢.
推荐答案
是的,有可能.无论您是在单个进程中的公寓之间还是在不同进程之间共享单个对象实例,基本原理都是相同的.
Yes, it's possible. The underlying principle is the same regardless of whether you are sharing a single object instance between apartments in a single process, or between separate processes.
这里有两种方法:也许最简单的是使用 运行对象表:这本质上是一个工作站范围的命名 COM 对象表.您让一个进程将一个具有众所周知名称的对象添加到表中,并让另一个进程查找该对象.
There's two approaches here: perhaps the simplest is to use the Running Object Table: this is essentially a workstation-wide table of named COM objects. You have one process add an object to the table with a well-known name, and have the other process look up that object.
另一种方法是使用编组.封送处理是使用 COM API 获取描述对象位置的一系列字节的过程.然后,您可以使用任何您想要的方式(共享内存、文件、管道等)将该系列字节复制到另一个进程,然后在接收进程中使用另一个 COM API 来解组对象;COM 然后在该进程中创建一个合适的远程代理,该代理与原始代理通信.查看 API CoMarshalInterface 和 CoUnmarshalInterface 了解更多详情.
The other approach is to use marshaling. Marshaling is the process of using a COM API to get a series of bytes that describe the location of an object. You can then copy that series of bytes to another process using any means you want to (shared memory, file, pipe, etc), and then use another COM API in the receiving process to unmarshal the object; COM then creates a suitable remoting proxy in that process that communicates back to the original one. Check out the APIs CoMarshalInterface and CoUnmarshalInterface for more details.
请注意,这两者都要求您为对象提供适当的远程支持;您使用的接口需要在 IDL 中进行描述,并进行适当的编译和注册.
Note that both of these require that you have suitable remoting support in place for the object; the interfaces you are using need to be described in IDL and compiled and registered appropriately.
--
不幸的是,我手头没有用于这两种情况的代码.
I don't have code handy for either of these cases unfortunately.
对于 CoMarshalInterface 方法,过程类似于:
For the CoMarshalInterface approach, the process is something like:
- 使用 CreateStreamOnHGlobal(hglobal 为 NULL)创建一个 IStream,该 IStream 由 COM 根据需要分配的 HGLOBAL 支持
- 使用 CoMarshalInterface 编组指向流的接口指针(依次将其写入 HGLOBAL 支持的内存)
- 使用 GetHGlobalFromStream 从流中获取 HGLOBAL
- 使用 GlobalLock/GlobalSize 锁定 HGLOBAL 并访问封组数据(完成后 GlobalUnlock)
- 使用任何你想将字节复制到目标进程的方法.
- Use CreateStreamOnHGlobal (with NULL hglobal) to create an IStream that's backed by a HGLOBAL that COM allocates as needed
- Use CoMarshalInterface to marshal the interface pointer to the stream (which in turn writes it to the memory backed by the HGLOBAL)
- Use GetHGlobalFromStream to get the HGLOBAL from the stream
- Use GlobalLock/GlobalSize to lock the HGLOBAL and access the marhaled data (GlobalUnlock when done)
- Use whatever means you want to to copy the bytes to the target process.
在远端,使用:
- GlobalAlloc/GlobalLock/GlobalUnlock 创建一个新的 HGLOBAL 并用封送数据填充它
- 使用您的新 HGLOBAL 创建StreamOnHGlobal
- 将此流传递给 CoUnmarshalInterface
- GlobalAlloc/GlobalLock/GlobalUnlock to create a new HGLOBAL and populate it with the marshaled data
- CreateStreamOnHGlobal with your new HGLOBAL
- Pass this stream to CoUnmarshalInterface
普通的 COM 和 Windows 引用计数/资源规则适用于所有这些;AddRef/Release 视情况而定;使用 GlobalFree 释放您分配的任何 HGLOBAL 等.
Normal COM and Windows refcounting/resource rules apply across all of this; AddRef/Release as appropriate; use GlobalFree to free any HGLOBALs that you allocate, etc.
相关文章