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!