TD x64

From Team Developer SqlWindows Wiki
Jump to: navigation, search

TD x64 versions (64Bit)


Contents


Pointer2.png External functions: structmember alignment on x64 (64 bit) Pointer.png

You might encounter issues when using TD x64 versions and using external function structures.


You have to be aware that a structure has specific requirements concerning the position of members within the structure.

The CPU in modern computer hardware performs reads and writes to memory most efficiently when the data is naturally aligned, which generally means that the data address is a multiple of the data size.

Data alignment refers to aligning elements according to their natural alignment.

To ensure natural alignment, it may be necessary to insert some padding between structure elements or after the last element of a structure.


WinAPI x64 structures require that pointers and handles need to be aligned at 8 byte boundaries.

This means that within a structure, a pointer/handle member must be at offsets 0, 8, 16, 24...


Looking at the beginning of OPENFILENAME structure


DWORD		lStructSize;
HWND		hwndOwner;
HINSTANCE	hInstance;
LPCTSTR		lpstrFilter;

etc etc

A DWORD is indeed 32 bits wide (4 bytes).

This makes this list of sizes and offsets:


TYPE		NAME		BYTES	OFFSET
DWORD		lStructSize;	4	0
HWND		hwndOwner;	8	4
HINSTANCE	hInstance;	8	12
LPCTSTR		lpstrFilter;	8	20


The second member, hwndOwner, is a handle. This means it must be on a 8 byte boundary.
But in this case, the offset will be at position 4, which is not a 8 byte boundary.


In such situations you need to have a FILLER value (internal padding). Between the first and second member to force the second member to be at offset 8.


In TD, when defining structures in external functions, the members are sequentially aligned, from top to bottom.
So, to force a FILLER, you have to define an extra member at the correct location having the correct filler size.
In this particular case, we need to add a 4 byte member between the first and second member, like this:


TYPE		NAME		BYTES	OFFSET
DWORD		lStructSize;	4	0
DWORD		FILLER		4	4
HWND		hwndOwner;	8	8
HINSTANCE	hInstance;	8	16
LPCTSTR		lpstrFilter;	8	24

When calling the external function, you need to pass in the extra parameter. Value is not important, but it is best to use zero's (0).


The OPENFILENAME structure has other members which need to be aligned to 8 byte boundaries.


The complete structure having all the needed FILLERS is displayed below:


StructureAlignment.png


The needed implementation for the structure above is shown in the sample which can be downloaded here:
Down.png SalDlgOpenFileStd_UNICODE_x86_x64.zip


For more detailed info on data structure padding see: