【发布时间】:2013-02-17 09:20:45
【问题描述】:
背景:
我正在连接 Windows COM 对象。
使用的方法是vtable修改。假设我们有一个名为instance的interface A实例,它在interface中包含oldmethod,我用newmethod替换.但是,在我的 newmethod 中,我需要知道 oldmethod 的地址,以便在做完自己的事情后调用 oldmethod。
将oldmethod的地址存储在全局变量中是不安全的,因为在interface A后面可能有多个实现,假设有两个实现、A1 级 和A2 级。因此我的newmethod需要同时存储A1->oldmethod和A2->oldmethod,并根据实例类型调用相应的函数。 p>
实现此目的的一种方法是我保留一个地图,其中存储(vtable 的地址 -> oldmethod)。由于 vtable 的地址可以作为 A1 类和 A2 类的区分符。在我的 newmethod 中,会检查地图以查找当前实例的正确 oldmethod。但是这样会让程序每次都要检查map,这会带来成本,而且map上的线程安全会增加成本。
1234563不是问题)。我在每个实例的二进制代码中修改 oldmethod 的地址。在这种情况下,地图成本上没有搜索。
问题 1:
第二种方法是否安全,还是第一种方法更好?是否存在安全隐患?
问题 2:
在第二种方式中,我创建的闭包包含特定于类的数据,即 oldmethod 指针。如果我需要在我的 newmethod 中存储特定于实例的数据,除了保留 (this pointer -> data) 映射之外,还有其他策略吗?我尽力了,还是找不到办法。
【问题讨论】:
-
是否有某些特定原因,您不只是从现有实现派生一个 coclass,而是用“newmethod”虚拟覆盖“oldmethod”签名必须匹配,否则你就是,根据定义,违反了 COM 对已发布 IID 和 pin 的接口的合同。当然,除非这不是您的代码(旧方法)并且您基本上是在尝试挂钩其他人的 coclass。您也可以使用 coclass-alias,但听起来您更喜欢偷偷地这样做。
-
我正在挂钩现有的 COM 对象以修改其行为,我没有实现。
-
@WhozCraig 而且我没有直接调用方法,我也没有调用者的代码。
-
“但是,这会让程序每次都检查地图,这会带来成本,而地图上的线程安全会增加成本。” - 这是一个非常假设无效。
-
我不明白为什么这个无效,你的意思是成本可以忽略不计?