【发布时间】:2014-02-24 05:22:09
【问题描述】:
作为简化案例:我需要通过现有的 COM 接口将 VARIANT 传输到另一个进程。我目前使用 MIDL 生成的编组器。
实际传输用于许多值,是时间关键过程的一部分,并且可能涉及大字符串或安全数组(几 MB),因此复制的数量似乎相关。
由于接收方需要在函数调用之外“保留”数据,因此封送拆收器至少需要制作一份副本。但是,我能想到的所有签名都包含两个副本:
SetValue([in] VARIANT)
GetValue([out] VARIANT *) // called by receiver
在这两种情况下,据我了解,编组器会制作一个跨进程副本,该副本确实会被编组器破坏。由于我需要将数据保存在接收器中,因此我需要制作第二份副本。
我考虑在接收器“分离”数据:
SetValue([in, out] VARIANT *)
// receiver detaches value and sets to VT_EMPTY for return
但这也会破坏源。
Q1:是否可以让 MIDL 生成的编组代码只执行一份副本?
Q2:这可以通过自定义编组器实现吗?以什么代价? (我第一次看到这非常令人沮丧)
我很想使用 SAFEARRAY 和/或其他 VARIANT/PROPVARIANT 类型,并传输整个数组。
[编辑]
双方都使用 C++,接口都是基于 IUnknown 的,并且需要在同一台机器上跨进程工作,在相同的上下文中。
【问题讨论】:
-
发送方(客户端)调用
SetValue,接收方(服务器)实现。这里是否有一些您没有提供的细节,例如发送者和接收者都是另一个远程对象的客户端?如果需要在中间有这样一个远程对象的两个实体之间进行传输,可以使用SetValue([in] IMyArray *)和GetValue([out] IMyArray **)其中IMyArray然后有GetArray([out] VARIANT *)。然后,接收方可以直接向发送方索取数组。 -
问题 1:这是否需要自动化兼容(即,可以从不同的语言调用)?如果是这样,你可能不走运。
-
问题 2:这必须跨机器工作,还是只在单台机器上跨进程工作?如果只是跨进程,那么编组会变得简单得多(您不需要构建花哨的线格式等)。
-
@EricBrown:查看更新,在一台机器上是 IUnknown。
-
@acelent:问题 - 至少据我所知 - 是编组器需要制作副本,并且没有办法告诉它不要释放它。这迫使我拥有第二份副本。
标签: c++ windows com marshalling