我们的接口从C ++ Builder的2010应用一些第三方COM对象。
目前,我们导入类型库,并生成组件的包装,然后能够做出方法调用和访问性能相当自然的方式。
object->myProperty = 42;
object->doSomething(666);
但是,我们一直在咬伤更改COM对象的接口(目前仍在扩大和发展),导致我们自己的应用程序失败,因为一些方法的GUID似乎得到无效的 - 即使到接口的唯一变化是加入一种新方法)。
后期绑定已被认为是解决这个问题的一种方式。 我认为,这需要我们的代码被改变,而这样的:
object.OlePropertySet("myProperty", 42);
object.OlePrcedure("doSomething", 666);
显然,这是痛苦的读写,所以我们不得不写包装类来代替。
有没有让我们导入类型库自动生成的后期绑定包装的方法吗? 而且,如果是的话,它们足够聪明,只是做文字时创建的对象,而不是在每一个方法调用绑定一次?
当您导入的TypeLibrary为支持后期绑定(当它实现了一个COM对象IDispatch
接口),进口商可以生成静态绑定和后期绑定独立的包装类(非组件)。
添加一个新的方法,以现有的接口不应该无效代码。 方法不具备的GUID。 然而,对于IDispatch
为基础的接口,它的方法确实有DISPID
与它们相关的值,这些DISPID
值可以从一个版本改变到另一个。 虽然任何可敬的COM开发者应该永远不会做,一旦一个接口的定义已被锁定。
由TLIBIMP生成的代码和头的深入调查后,事实证明这是相当容易的。
如果您的类型库有一个类Foo
,然后导入类型库后,您通常使用自动生成的智能指针类IFooPtr
。
{
IFooPtr f;
...
f->myMethod(1,2);
}
你应该注意到,在这一点上的绑定是静态的 - 也就是说,他们不仅取决于对象的GUID和方法的dispid的,但在虚函数表的DLL中的准确布局。 影响虚表的任何变化-例如,添加额外的方法将基类的Foo
将导致方法调用失败。
要使用动态绑定,您可以使用IFooDisp
类,而不是IFooPtr
。 同样,这些智能包装,自动处理对象的寿命。 请注意,这些类,你应该使用.
运营商的接入方式,而不是间接->
操作。 使用间接运算符将调用该方法,而是通过一个静态绑定。
{
IFooDisp f;
...
f.myMethod(1,2);
}
通过使用这些IDispatch
为基础的包装,方法将他们的DISPID出动,即使对象虚表的布局发生变化。 我觉得这些课程也给了一种通过函数的名称,而不是DISPID调度,但还没有证实的是细节。