Previous lessons in this course discussed making changes to external_function definitions. This lesson goes into one specific aspect of that, which is “structure padding.” It’s important to know what it is, and how to recognize that changes to structs need to be made when preparing for 64-bit.
Structure padding is not a completely new issue, but with 64-bit it becomes much more relevant. This is because Windows’ functions, and most third party dependencies (ex: written in C or C-sharp), apply structure padding within structs, also called structure alignment. Dataflex does not do that.
What is structure padding? In C/C++ or others, structs can contain extra empty space. This is for efficiency reasons (note: does increase the size of the struct).
This Windows struct has two integers, each 4 bytes, then two char items, each 1 byte and finally a float, which is 4 bytes. The expectation is for the struct size to be 14 bytes in total, but it will actually be 16 bytes. Items in structs are grouped and allotted a chunk of bytes. The size of the chunk is determined by the size of the largest struct member in order to align the data. In this example, the size is 4 bytes, since the integer is the largest member. ‘Id1’ and ‘Id2’ each have their own 4-byte chunk. Then there are two bytes for the chars ‘name’ and ‘c,’ but the next item is 4 bytes, and that does not fit in the remaining space of the chunk. It therefore has to start at the beginning of a new chunk of 4 bytes. Two bytes are skipped, these are empty. Here is another example. This struct has the same data but is less efficiently defined. There are two empty spaces of 3 bytes each. The size of this struct is 20 bytes.
Why is structure padding more relevant in 64-bit? This is because of structs that contain Pointers and platform dependent integer types. These set the chunk size to 8 bytes in 64-bit, whereas it was 4 bytes in 32-bit. Take this example:
In 32-bit, all struct members are 4 bytes, so the chunk size is 4 bytes and there is no added empty space. In a 64-bit compilation, the chuck size is 8 bytes because of the Pointer and LParam members. It would result in the following memory usage. Notice the two times 4 bytes of empty space. As previously mentioned, DataFlex does not do structure padding, so there are no empty spaces in DataFlex structs.
Now, when structs are defined in DataFlex that will be passed via the external_function, the memory alignment must be made to be equal to what is expected on the other side. This means that extra spaces may need to be added manually.