PDA

View Full Version : DF20 Breaking Changes



jason
2-Mar-2022, 10:48 PM
Hi DAW/All,

Thought I'd just raise this here. We have been migrating various projects from prior version of DF (17.1, 18.0, 18.2, 19.1 etc) to DF 20.0 and have recently encountered some breaking changes that I've noticed in both these classes:
cXmlHttpTransfer.pkg
cJsonHttpTransfer.pkg

In cXmlHttpTransfer.pkg (prior to DF20):


{ Visibility=Private }
Property Address paDataReceived 0 // maintained by object


In DF20:


{ Visibility=Private }
Property Pointer ppDataReceived 0 // maintained by object



In cJsonHttpTransfer.pkg (prior to DF20):


{ Visibility=Private }
Property Address paDataReceived 0 // maintained by object

{ Visibility=Private }
Property Integer piDataReceivedLength 0 // maintained by object

In DF20:


{ Visibility=Private }
Property UChar[] pucDataReceived // maintained by object

***piDataReceivedLength removed***



I will start by saying these don't appear to be documented properties that have changed, but nonetheless, the documentation for both these classes (within the internal code comments) doesn't appear to advise against accessing these properties or relying on them in subclasses. After all, the intention of OOP is to allow subclassing and overloading and these are common/shared libraries?

To avoid a bunch of additional risk and testing, the simplest way has been to add #IF (!@ >= 200) or #IF (!@ < 200) compiler flags everywhere through our existing code and libraries.

I have also noticed during upgrade of an old web app the following change:
cBaseWebApp.pkg no longer exists in DF20, appears to be now renamed or replaced (closest class I could find) with cWebAppBasic.pkg?

Other points I thought I'd mention:


Pointer is stated to be simply an alias for Address (the native data type according to DF20 and prior documentation), but it has been made obsolete in DF20. It is quite amusing as the function to obtain an Address (AddressOf), is also the function to obtain a Pointer, which now returns a Pointer rather than an Address. Do we expect this to change in future DF versions (e.g. PointerOf function that may break code)?
Have also noticed during upgrades errors for lack of PointToString function usage where previously (< DF20.0) you could move a Pointer/Address to a string and get this casted automatically (via Compiler or Runtime I assume?), is there any reason this behavior has changed in DF20 onwards - if the compiler sees it, why can't it optimise during compile/fix this?
Can no longer Move a string to a Address/Pointer, you must use MemCopy
Strings passed to a function (such as MemCopy) that requires Pointer/Address no longer accept a string variable, you must call AddressOf(string variable) for example - no longer casting during compile?
DF20 Compiler does not appear to be picking up lack of 'PointerToString' usage when calling Move to a struct property that is a string, this results in a runtime error (e.g. Move pPointer to SomeStruct.sString) Illegal Datatype Conversion.


I hope the above can help someone else with their upgrades, and please feel free to add/contribute to any know gotchas with the introduction of DF20. Would love to hear back from DAW regarding the above changes

Harm Wibier
3-Mar-2022, 03:04 AM
Thanks for your feedback..
FYI: I moved this thread to the Unicode & 64-bit forums.

cXmlHttpTransfer and cJsonHttpTransfer
Private properties are part of the private implementation of a class. When accessing those from a subclass or outside the class you do that at your own risk. While we do care a lot about backwards compatibility, we do sometimes refactor things to improve them.

Basic WebApp
The cWebApp class structure changes where actually made in 19.1 (https://docs.dataaccess.com/dataflexhelp/index.htm#t=mergedProjects%2FWelcome%2FWhat_s_New_ in_DataFlex_2019_19.1.htm). The cBaseWebApp class actually became a mixin. The goal was to support non Framework applications better without having to load many UI classes that you were not using. So, if you have a webapp that only runs web-services, classic asp or custom HTTP handlers then cWebAppBasic (https://docs.dataaccess.com/dataflexhelp/mergedProjects/VDFClassRef/cWebAppBasic.htm) is now the best (and cleanest) class to use.

Pointer vs Address
Before 20.0 pointer was actually a replace for integer, which is fine in the 32-bit world but 64-bit pointers do not fit inside integers. Our code contained a mix of Pointer, Address and Integer usage to store memory addresses. So to resolve the issue with pointer, and in an attempt to clean things up, we decided to change Pointer to become the same as Address and deprecate the usage of the Address name in favor of pointer (more consistent with other languages). The address indeed has some special powers with regards to strings and these actually became in issue with how pointer was used in some places, which is why we had to remove this. We then added errors to the compiler to help you find the cases where these special features where used, but unfortunately we could not make that detection watertight (DataFlex isn't very strictly typed), of which you obviously found an example.

So, to get the memory address to the value of a string variable use AddressOf (https://docs.dataaccess.com/dataflexhelp/index.htm#t=mergedProjects%2FLanguageReference%2FA ddressOf.htm). To create a copy of that string value use MemCopy (https://docs.dataaccess.com/dataflexhelp/index.htm#t=mergedProjects%2FLanguageReference%2FM emCopy.htm)(and do your own allocations), or change you code to use something like a UChar array. If you have a pointer to a memory block containing a string use PointerToString (https://docs.dataaccess.com/dataflexhelp/index.htm#t=mergedProjects%2FLanguageReference%2FP ointerToString.htm)which will copy the value into a string variable you can then use. We believe that with these changes the code actually becomes more readable.

jason
3-Mar-2022, 05:32 PM
Thanks for your feedback..
FYI: I moved this thread to the Unicode & 64-bit forums.

cXmlHttpTransfer and cJsonHttpTransfer
Private properties are part of the private implementation of a class. When accessing those from a subclass or outside the class you do that at your own risk. While we do care a lot about backwards compatibility, we do sometimes refactor things to improve them.

Basic WebApp
The cWebApp class structure changes where actually made in 19.1 (https://docs.dataaccess.com/dataflexhelp/index.htm#t=mergedProjects%2FWelcome%2FWhat_s_New_ in_DataFlex_2019_19.1.htm). The cBaseWebApp class actually became a mixin. The goal was to support non Framework applications better without having to load many UI classes that you were not using. So, if you have a webapp that only runs web-services, classic asp or custom HTTP handlers then cWebAppBasic (https://docs.dataaccess.com/dataflexhelp/mergedProjects/VDFClassRef/cWebAppBasic.htm) is now the best (and cleanest) class to use.

Pointer vs Address
Before 20.0 pointer was actually a replace for integer, which is fine in the 32-bit world but 64-bit pointers do not fit inside integers. Our code contained a mix of Pointer, Address and Integer usage to store memory addresses. So to resolve the issue with pointer, and in an attempt to clean things up, we decided to change Pointer to become the same as Address and deprecate the usage of the Address name in favor of pointer (more consistent with other languages). The address indeed has some special powers with regards to strings and these actually became in issue with how pointer was used in some places, which is why we had to remove this. We then added errors to the compiler to help you find the cases where these special features where used, but unfortunately we could not make that detection watertight (DataFlex isn't very strictly typed), of which you obviously found an example.

So, to get the memory address to the value of a string variable use AddressOf (https://docs.dataaccess.com/dataflexhelp/index.htm#t=mergedProjects%2FLanguageReference%2FA ddressOf.htm). To create a copy of that string value use MemCopy (https://docs.dataaccess.com/dataflexhelp/index.htm#t=mergedProjects%2FLanguageReference%2FM emCopy.htm)(and do your own allocations), or change you code to use something like a UChar array. If you have a pointer to a memory block containing a string use PointerToString (https://docs.dataaccess.com/dataflexhelp/index.htm#t=mergedProjects%2FLanguageReference%2FP ointerToString.htm)which will copy the value into a string variable you can then use. We believe that with these changes the code actually becomes more readable.

Thank you for clarifying cWebAppBasic, this is what I had ended up with after cross referencing the old and new documentation but always good to have it confirmed!

Regarding Address/Pointer, the documentation that shipped with DataFlex 2021 states both as having a range of 0 to 4,294,967,296, hence a bit of confusion regarding the changes that were made - but I can see the latest online help is showing correctly the 2^32-1 and 2^64-1 values :)