使用C ++ Builder将COM对象延迟绑定

时间:2012-07-26 13:17:11

标签: c++ com c++builder late-binding

我们正在与C ++ Builder 2010应用程序中的某些第三方COM对象进行交互。

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

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

然而,我们被COM对象的接口(仍在扩展和开发)的更改所困扰,导致我们自己的应用程序失败,因为某些方法GUID似乎无效 - 即使对接口的唯一更改已经是一种新方法的补充。)

后期绑定已被建议作为解决此问题的方法。我认为这需要更改我们的代码rather like this:

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

显然读取和写入都很痛苦,所以我们必须编写包装类。

导入类型库时,是否有任何方法可以自动生成后期绑定包装器?而且,如果是这样,他们是否足够聪明,只能在创建对象时进行一次文本绑定,而不是每次调用方法?

2 个答案:

答案 0 :(得分:3)

当您为支持后期绑定的COM对象导入TypeLibrary时(当它实现IDispatch接口时),导入器可以为静态绑定和后期绑定生成单独的包装类(而不是组件)

向现有接口添加新方法不应使代码无效。方法没有GUID。但是,对于基于IDispatch的接口,其方法确实具有与其关联的DISPID值,并且这些DISPID值可以从一个版本更改为另一个版本。虽然任何可敬的COM开发人员都应该在锁定接口定义后再这样做。

答案 1 :(得分:0)

经过对TLIBIMP生成的代码和标题的深入调查后,结果非常简单。

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

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

您应该注意到,此时绑定是静态的 - 也就是说,它们不仅依赖于对象的GUID和方法的DISPID,还依赖于DLL中VTable的确切布局。任何影响vtable的更改 - 例如,向基类Foo添加其他方法都将导致方法调用失败。

要使用动态绑定,您可以使用IFooDisp类而不是IFooPtr。同样,这些是智能包装器,自动处理对象的生命周期。请注意,对于这些类,您应该使用.运算符来访问方法,而不是间接->运算符。使用间接运算符将调用该方法,但是通过静态绑定。

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

通过使用这些基于IDispatch的包装器,即使更改了对象vtable布局,也会通过其DISPID调度方法。我认为这些类还提供了一种按函数名称而不是DISPID进行分派的方法,但尚未确认其详细信息。