In Borland C++ Builder 6, the code generated to import COM objects slightly differs from the one generated by previous versions of C++ Builder.
Specifically, the VARIANT date type is used instead of TVariant. Giving up its TVariant « smart wrapper » was a good move from Borland, but it broke backward compatibility with output parameters of some COM methods, which don’t receive a value anymore.
For example, below is the code generated by C++ Builer 4 for the FarPoint TfpSpread COM object (from file FPSpreadADO_TLB.h) :
[code lang=cpp]
  VARIANT_BOOL __fastcall GetText(long Col, long Row, TVariant* Var)
 {
    _TDispID _dispid(/* GetText */ DISPID(252));
    TAutoArgs<3> _args;
    _args[1] = Col /*[VT_I4:0]*/;
    _args[2] = Row /*[VT_I4:0]*/;
    _args[3] = Var /*[VT_VARIANT:1]*/;
    OleFunction(_dispid, _args);
    return _args.GetRetVariant();
  }
[/code]
When generated using C++ Builder 6, the code becomes :
[code lang=cpp]
  VARIANT_BOOL __fastcall GetText(long Col, long Row, VARIANT* Var)
 {
    _TDispID _dispid(/* GetText */ DISPID(252));
    TAutoArgs<3> _args;
    _args[1] = Col /*[VT_I4:0]*/;
    _args[2] = Row /*[VT_I4:0]*/;
    _args[3] = Var /*[VT_VARIANT:1]*/;
    OleFunction(_dispid, _args);
    return _args.GetRetVariant();
  }
[/code]
Notice the Var parameter, whose type was changed from TVariant* to VARIANT* : that’s the source of the problem.
The issue comes from the TAutoArgs class, more specifically from its array of Variant.
The Variant assignment operator (=) behaves differently depending if its RHS is a TVariant* or a VARIANT* :
- Variant = TVariant*: The- Variantis initialized with a reference to the- TVariant*object (- vt = VT_BYREF|VT_VARIANT, and- pvarValreceives a pointer to the- TVariant*
- Variant = VARIANT*: the- Variant‘=’ operator assumes the- VARIANT*is a- VT_BOOL. Changes to the- Variantare not reflected on  the- VARIANT*
To fix the problem, one must explicitly set the Variant as a reference to the VARIANT*. For example, the previous example must be changed to :
[code lang=cpp]
  VARIANT_BOOL __fastcall GetText(long Col, long Row, VARIANT* Var)
 {
    _TDispID _dispid(/* GetText */ DISPID(252));
    TAutoArgs<3> _args;
    _args[1] = Col /*[VT_I4:0]*/;
    _args[2] = Row /*[VT_I4:0]*/;
    _args[3].vt = VT_BYREF|VT_VARIANT /*[VT_VARIANT:1]*/;
    _args[3].pvarVal = Var;
    OleFunction(_dispid, _args);
    return _args.GetRetVariant();
  }
[/code]
Président et fondateur de NeoLegal, développe des solutions logicielles qui facilitent le quotidien des professionnels du droit des sociétés.