Late Binding COM Objects with C ++ Builder

We interact with some third-party COM objects from a C ++ Builder 2010 application.

We are currently importing a type library and creating component wrappers, and then we can make method calls and access properties in a fairly natural way.

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

However, we were bitten by changes to the interface of the COM object (which is still expanding and developing), which leads to the failure of our own application, because some GUID methods seem invalid - even if the only change to the interface was adding a new method).

Late binding has been proposed as a way to solve this problem. I think that for this we need to change our code as follows:

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

Obviously, it hurts to read and write, so we have to write wrapper classes.

Is there a way to get late binding wrappers generated automatically when importing a type library? And if so, are they smart enough to perform text bindings once when the object is created, and not on every method call?

+5
source share
2 answers

When importing a TypeLibrary for a COM object that supports late binding (when it implements the IDispatch interface), the importer can create separate wrapper classes (rather than components) for both static binding and late binding.

Adding a new method to an existing interface should not invalidate the code. Methods do not have GUIDs. However, for the IDispatch interface, its methods have DISPID values ​​associated with them, and those DISPID values ​​can be changed from one version to another. Although any reputable COM developer should never do this once the interface definition has been blocked.

+3
source

After deeply studying the code and headers generated by TLIBIMP, this is pretty easy.

If your type library has the Foo class, then after importing the type library you usually use classes with automatic creation of smart IFooPtr pointers.

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

It should be noted that at this moment the bindings are static, that is, they depend not only on the GUIDs of the objects and DISPIDs of the methods, but also on the exact location of the VTable in the DLL. Any changes that affect vtable - for example, adding an additional method to the Foo base class will cause the method call to fail.

To use dynamic bindings, you can use the IFooDisp classes instead of IFooPtr . Again, these are smart wrappers that automatically control the life cycle of objects. Note that you must use a statement with these classes . for access to methods, and not for the indirectness operator -> . Using the indirectness operator will invoke the method, but through static binding.

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

Using these wrappers based on IDispatch , methods will be dispatched by their DISPID, even if the format of the vtable objects is changed. I think that these classes also make it possible to send by function name, not DISPID, but did not confirm the details of this.

0
source

Source: https://habr.com/ru/post/948393/


All Articles