#1 2014-03-29 15:44:55

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 12,721
Website

Enhanced and fixed late-binding of variants for Delphi XE2 and up

Since Delphi XE2, some modifications were introduced to the official DispInvoke() RTL implementation:
- A new varUStrArg kind of parameter has been defined, which will allow to transmit UnicodeString property values;
- All text property values would be transmitted as BSTR / WideString / varOleStr variants to the invoked variant type;
- All textual property names were normalized to be in UPPERCASE.

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.

Since revision 1.18 of the framework, the patch described in this Design Input 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. 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 for Blog article http://blog.synopse.info/post/2014/03/2 … XE2-and-up

Offline

#2 2014-03-29 15:59:37

martin.suer
Member
Registered: 2013-12-15
Posts: 76

Re: Enhanced and fixed late-binding of variants for Delphi XE2 and up

This is great, I have seen that symptom yesterday but you're fixing issues before one is reporting it ... :-)

Offline

Board footer

Powered by FluxBB