用C ++ Builder中后期绑定的COM对象(Late Binding COM objects

2019-06-26 13:37发布

我们的接口从C ++ Builder的2010应用一些第三方COM对象。

目前,我们导入类型库,并生成组件的包装,然后能够做出方法调用和访问性能相当自然的方式。

object->myProperty = 42;
object->doSomething(666);

但是,我们一直在咬伤更改COM对象的接口(目前仍在扩大和发展),导致我们自己的应用程序失败,因为一些方法的GUID似乎得到无效的 - 即使到接口的唯一变化是加入一种新方法)。

后期绑定已被认为是解决这个问题的一种方式。 我认为,这需要我们的代码被改变,而这样的:

object.OlePropertySet("myProperty", 42);
object.OlePrcedure("doSomething", 666);

显然,这是痛苦的读写,所以我们不得不写包装类来代替。

有没有让我们导入类型库自动生成的后期绑定包装的方法吗? 而且,如果是的话,它们足够聪明,只是做文字时创建的对象,而不是在每一个方法调用绑定一次?

Answer 1:

当您导入的TypeLibrary为支持后期绑定(当它实现了一个COM对象IDispatch接口),进口商可以生成静态绑定和后期绑定独立的包装类(非组件)。

添加一个新的方法,以现有的接口不应该无效代码。 方法不具备的GUID。 然而,对于IDispatch为基础的接口,它的方法确实有DISPID与它们相关的值,这些DISPID值可以从一个版本改变到另一个。 虽然任何可敬的COM开发者应该永远不会做,一旦一个接口的定义已被锁定。



Answer 2:

由TLIBIMP生成的代码和头的深入调查后,事实证明这是相当容易的。

如果您的类型库有一个类Foo ,然后导入类型库后,您通常使用自动生成的智能指针类IFooPtr

{
  IFooPtr f;
  ...
  f->myMethod(1,2);
}

你应该注意到,在这一点上的绑定是静态的 - 也就是说,他们不仅取决于对象的GUID和方法的dispid的,但在虚函数表的DLL中的准确布局。 影响虚表的任何变化-例如,添加额外的方法将基类的Foo将导致方法调用失败。

要使用动态绑定,您可以使用IFooDisp类,而不是IFooPtr 。 同样,这些智能包装,自动处理对象的寿命。 请注意,这些类,你应该使用. 运营商的接入方式,而不是间接->操作。 使用间接运算符将调用该方法,而是通过一个静态绑定。

{
  IFooDisp f;
  ...
  f.myMethod(1,2);
}

通过使用这些IDispatch为基础的包装,方法将他们的DISPID出动,即使对象虚表的布局发生变化。 我觉得这些课程也给了一种通过函数的名称,而不是DISPID调度,但还没有证实的是细节。



文章来源: Late Binding COM objects with C++Builder