Make your applications work in DataFlex NextGen
Document scope and public resources
This is a document that is Work In Progress as it is based on information shared by Data Access in public. The scope of this document is to assist in helping making your application or library work in DataFlex NextGen.
The following presentations are available in public:
- DataFlex NextGen by John de Froe at Scanduc 2018.
- Getting your applications ready for DataFlex NextGen by Stephen Meeley at Synergy 2019
- DataFlex NextGen by Harm Wibier at Synergy 2019
Also read the following in the documentation:
As indicated there, things might still change.
Refactor obsolete code
If you want to get your applications ready for DataFlex NextGen then compile your app in DataFlex 19.1 and enable the warnings. Start by fixing all those warnings (tip: DfRefactor can help you with this, as can Starzen's DataFlex Source code browser.
The following is important if you want to be able to run NextGen:
- Obsolete commands have to be eliminated
- String commands have to be replaced by string functions as string commands will not support Unicode
- Indicators have to be eliminated
- Type/End_Type has to be replaced with Struct/End_Struct, see DataFlex 19.1 package tWinStructs.pkg for an example. Note that there might be different padding rules for 32 and 64 bits.
- Obsolete classes
- Obsolete packages
- Obsolete global functions
- Obsolete key words (public, private, local)
The compiler will show warnings for all of the above.
64 bits support
variable types
LongPtr
This is an integer type that equals the size of a Pointer depending on the platform.
eg.
32 bits long on the 32 bits platform 64 bits long on the 64 bits platform
An example is window messages
Integer
Stays the same, always is and will continue to be 32 bits
Pointer
Used to be a replace for integer, now it is an address
Legacy DataFlex:
#REPLACE Pointer Integer
NextGen DataFlex:
#REPLACE Pointer Address
Handle
Used to be a replace for integer, now it is LongPtr
Legacy DataFlex:
#REPLACE Handle Integer
NextGen DataFlex:
#REPLACE Handle LongPtr
In DataFlex the Handle type is used for DataFlex objects as well as for Windows Handles.
In 32 bits, they are 32 bits long.
In 64 bits, the DataFlex are still 32 bits, but the Windows Handles are usually 32 bits, but in a 64 bit container where almost always the extra 32 bits are padded.
Do _not_ use handles for pointers, a handle is not a memory address
New Compiler switch
#IF IS$WIN64 .. your 64 bits code #ELSE .. your 32 bits code #ENDIF
Migrating your application to 64 bits
If you compile your application for 64 bits then all the components it is using also have to be 64 bits.
This means that your DLLs and ActiveX components have to be 64 bits as well.
Most likely you will have to update your DLL wrappers for this support.
Patching your external API wrappers
Look out for invalid use of "integer".
You might need to change integer into LongPtr where an integer was used for pointers.
You can start with your preparation for 64 bits in DataFlex 19.1 !
There's an alias for LongPtr in DataFlex 19.1
Calling conventions
In DataFlex 20 you should use the following calling conventions for your external DLLs
- 32 bit: stdcall
- 64 bit: fastcall
See also: Calling conventions
The DF20 runtime uses the library libffi to make the call.
It is possible that for 32 bit the cdecl calling convention also works now, but it has so far only seen limited testing.
Unicode Support
Characters are no longer just 1 byte long, but instead can have a variable size and can be up to 4 bytes per character.
This has an affect on your string functions.
For example the length of a string and the position of your character is no longer as easy to determine.
Variable types
String
- The DataFlex String becomes unicode
- UTF-8 is the default encoding
- With UTF-8, the first 128 characters are the same as ASCII, making it backwards compatible.
- DataFlex Web already uses UTF-8
- Windows uses UTF-16, so you will have to change the encoding from/to when making API calls. In addition to that instead of calling the "A" variant of the API you now have to call the "W" version of that API call. The conversion would be along these lines:
- Convert your string from UTF-8 to UTF-16
- Call the "W" variant of the function
- Convert a returned string from UTF-16 to UTF-8
- Down here you don't use ToOEM/ToANSI anymore as it is not needed.
DAW is hoping to be able to get rid of argument_size with NextGen.
Areas where you are using strings to manipulate memory may need to be changed.
Source
DataFlex source code will be stored in UTF-8
The symbols in the language will remain to be ASCII only.
Literals can contain Unicode characters
Database
SQL is the preferred database type.
MSSQL has unicode datatypes (he "n" variants) : nvarchar, nchar, nvarchar(max), ntext
MSSQL 2019 will support UTF-8
At this moment there is not final decision on what the embedded database support with unicode will be.
Migrating to Unicode
If you see ToOEM or ToANSI in your DLL or ActiveX Wrappers that means something has to be changed as you don't need it anymore when using Unicode.
Bytes are not code points, one character can take up to 4 bytes.