The issues

The first modification does make sense, and was indeed a welcome fix for an Unicode version of Delphi. It should have been as such since Delphi 2009.

Temporary conversion to WideString does make sense in the COM / OLE world, but is an awfull performance bottleneck in the pure Delphi realm, i.e. when using late-binding with custom type of variants (as for all our custom variant types). This may be a noticeable speed penalty, in comparison to previous versions of the compiler.

Last but not least, the conversion to uppercase is a bug. For instance, the following code won't work as expected since Delphi XE2:

var V: variant;
 ...
  TDocVariant.New(V); // or slightly slower V := TDocVariant.New;
  V.name := 'John';
  V.year := 1972;
  // before Delphi XE2, V contains {"name":"john","year":1982} - as expected
  // since Delphi XE2,  V contains {"NAME":"john","YEAR":1982} - sounds like a bug, doesn't it?

This sounds indeed like an awfull regression.

Fix included in the mORMot framework

Since revision 1.18 of the framework, the patch described in this previous blog article has been modified for Delphi XE2 and up, as such:

  • It will handle varUStrArg kind of parameter as exepcted;
  • It will avoid any temporary conversion to WideString for textual values;
  • It will by-pass the property name change into uppercase.

As soon as you define SynCommons in any of your program's uses class, our hooked DispInvoke() will take place, and identify any of our TSynInvokeableVariantType classes.

As a result, it will by-pass the performance bottleneck of the default RTL implementation, and also fix the uppercase conversion of the property name.

Of course, if this variant is not a TSynInvokeableVariantType instance (e.g. any Ole Automation call), the regular TInvokeableVariantType.DispInvoke() method as defined in Variants.pas will be executed, to maintain the best compatibility possible.

Feedback is welcome in our forum, as usual!