Migrating to DataFlex 2021, Part 3
Lesson 14 – External APIs
The next step in this course is to learn how to adapt applications to use 64-bit external APIs. It is important to use the right datatype when interfacing with Windows and other external APIs. This includes the External_function calls, notifications and structs that are passed. All of these may work in 32-bit but might break in 64-bit. Longptr and ULongptr types will be needed for interfacing platform dependent integer types, such as the C/C++ types, INT_PTR, LRESULT, WPARAM, ULONG_PTR, Size_t, etc.
DEMONSTRATION
- This is an external_function definition for a windows function.
- Is it correct? In the MSDN documentation, two Pointers are expected and a SIZE_T variable. SIZE_T is a platform-dependent unsigned integer type, so a ULongptr needs to be used.
- In the code, there are two correct Pointers, but the third one, UInteger, needs to be corrected.
- Windows automatically knows whether to call it from the 32- or 64-bit DLL.
- Here is a list of often used Windows datatypes, and which datatype should be used in DataFlex.
-
- Strings can still be passed as String, which is convenient, but they can also be passed as a Pointer to the string. Longptr is the best choice for types like lParam, wParam, Int_ptr and others, while ULongptr is appropriate for types like, Size_t and Dword_ptr.
- Third party dependencies, such as DLLs and COM controls, must be 64-bit to be able to compile an application as 64-bit. It may need to be downloaded, but an alternative may need to be found if one is not available. If the source is available, recompile it as 64-bit.
- An example with a third-party dependency
- Shown is an External_function called ShowMyDialog, which is called from the MyDialogs.dll with a mistake; the second parameter should be a Handle, not Integer.
- Assuming a 64-bit version of this DLL, called MyDialogs64.dll, has been obtained. It needs to be implemented so that it calls the 32-bit version when running 32-bit, and 64-bit when running 64-bit. One option is to put 32- and 64-bit applications in separate folders, and in each folder there is the MyDialogs DLL with identical names (MyDialogs.dll). Alternatively, both the 32- and 64-bit DLLs are put in the same folder. The IS$WIN64 compiler switch would have to be used, a copy of the external_function definition would have to be made, and the first one to call MyDialogs64.dll wouldhave to be changed.
- This is how the external_function definitions of Windows and third-party APIs for 64-bit are changed. In addition to using the correct datatypes for parameters, the underlying data when a Pointer is passed may need to be changed, especially when structs are passed. There is a peculiar phenomenon called “structure padding” that may need attention. This will be discussed in the following lesson.