When working with libraries (and especially the Windows API), how we pack our data is essential to transfer data back and forth from our programs to their respective library functions. A perfect example is the recent windows printer dialog which I just put up. In it, we need to transfer data back and forth which meets this data requirement:
TYPE PRINTDLGEX
lStructSize AS _UNSIGNED LONG
hwndOwner AS _UNSIGNED _OFFSET ' HWND
hDevMode AS _UNSIGNED _OFFSET ' HGLOBAL
hDevNames AS _UNSIGNED _OFFSET ' HGLOBAL
hDC AS _UNSIGNED _OFFSET ' HDC
Flags AS _UNSIGNED LONG
Flags2 AS _UNSIGNED LONG
ExclusionFlags AS _UNSIGNED LONG
nPageRanges AS _UNSIGNED LONG
nMaxPageRanges AS _UNSIGNED LONG
lpPageRanges AS _UNSIGNED _OFFSET ' LPPRINTPAGERANGE
nMinPage AS _UNSIGNED LONG
nMaxPage AS _UNSIGNED LONG
nCopies AS _UNSIGNED LONG
hInstance AS _UNSIGNED _OFFSET ' HINSTANCE
lpPrintTemplateName AS _UNSIGNED _OFFSET ' LPCSTR
lpCallback AS _UNSIGNED _OFFSET ' LPUNKNOWN
nPropertyPages AS _UNSIGNED LONG
lphPropertyPages AS _UNSIGNED _OFFSET ' HPROPSHEETPAGE *
nStartPage AS _UNSIGNED LONG
dwResultAction AS _UNSIGNED LONG
END TYPE
In 32-bit windows, this data type is perfectly fine the way it is to work with PrintDlgExA. In 64-bit windows, it'll glitch out and toss us an error message.
What's the difference?
32-bit windows expects the data to be packed in 4-byte segments. 64-bit windows expects it to be packed in 8-byte segments... This means we have to toss some padding into the file to manually add extra space onto some of those longs, such as below.
TYPE PRINTDLGEX
lStructSize AS _UNSIGNED LONG '4 bytes
PADDING AS LONG 'we need 4 bytes of padding here, so that we keep our data lined up into 8byte segments properly
hwndOwner AS _UNSIGNED _OFFSET ' HWND '8 bytes since we're in 64-bit mode, so this is fine.
You guys who are more familiar with coding in C than I am, have probably dealt with this issue much more than I ever had. At best, I only claim to be an untalented hack when it comes to working with C -- I'm still learning and improving with the language all the time...
My question here is:
Is there some simple way to define how to pack a data structure with use for DECLARE LIBRARY like this?
If we were to code this in C, we'd use a command similar to one of the following:C++11's alignas(1)
struct __attribute__ ((packed)) BMPHeader
#pragma pack(1)
But how the heck would we do this within QB64 itself? Is it even possible? Or do I just got to stick to the basics when dealing with these situations and just manually add in some blank padding where it's needed to maintain the structure, as I did in this case to make it work for me??
Any guidance/advice from you guys who have dealt with these type of issues before can give is greatly appreciated. Seems to me like there should be some simple way to handle these type of things, but if not, one can always just manually pad the structure themselves when it's needed. (As long as you can decipher any error messages and come to the realization that that's what the problem is!)