No amount of documentation will help if you do not know how a structure is
packed immediately before passing it to an API. I have seen "C" program
with multiple occurrences of
#pragma pack statements buried with #include files that are make it almost
impossible to figure out how a structure is packed. For instance a SCI
driver typically need structure member that are not padded, exp #pragma
pack(1) . A Win32 API may not require this so later in an include file
there may be a #pragma pack which changes to compiler back to the default
packing. Also be aware that the /ZPn option does not override the #pragma
pack option.
What makes this problem even worse is when trying to interface to different
languages such a VB or Delphi. Each of these languages pad structures
differently than "C" and these compilers do not have options to changes
the packing.
I think the Conrad's method of determining the offset into the structure
using offsetof is right on!
Does Swiftforth have the ability to change the structure packing? If so
this would be an easier way to address the issue because once the structure
packing was determined a Swiftforth option could be enabled to padd the
structure appropiately.
-----Original Message-----
From: Conrad Weyns [SMTP:weyns_at_online.no]
Sent: Monday, April 16, 2001 8:14 AM
To: sftalk_at_forth.com
Subject: [sftalk] Re: C Structures
>
>Hello all. I'm attempting to put together a document (which I will
>post for comment) describing how to interpret C structures for use in
>a SwiftForth program. Windows makes extensive use structures in the
>API and these structures are typically documented using C struct
>statements. Unless one is "C Literate", it can be difficult to
>translate the syntax. C compilers can, depending on compiler
>directives, pad variables to byte, word or dword boundaries adding
>another layer of complexity (confusion).
As far as interfacing to the MS Win32 API is conserned, compilers cannot=
take liberties.
In fact, you should stick to the Microsoft documentation on this issue,
not C references.
Look into MSDN "Storage and Alignment of Structures"
Here are some points:
---- Quote start ----
Microsoft Specific
Structure members are stored sequentially in the order in which they are=
declared:
the first member has the lowest memory address and the last member the
highest.
Every data object has an alignment-requirement.
For structures, the requirement is the largest of its members.
Every object is allocated an offset so that
offset % alignment-requirement =3D=3D 0
Adjacent bit fields are packed into the same 1-, 2-, or 4-byte allocatio=
n
unit if the integral types are the same size and if the next bit field
fits into the current allocation unit without crossing the boundary
imposed by the common alignment requirements of the bit fields.
To conserve space or to conform to existing data structures, you may wan=
t
to store structures more or less compactly. The/Zp[n] compiler option an=
d
the#pragma pack control how structure data is =ECpacked=EE into memory. =
When
you use the /Zp[n] option, where n is 1, 2, 4, 8, or 16, each structure
member after the first is stored on byte boundaries that are either the
alignment requirement of the field or the packing size (n), whichever is=
smaller. Expressed as a formula, the byte boundaries are the
min( n, sizeof( item ) )
where n is the packing size expressed with the /Zp[n] option and item is=
the structure member. The default packing size is /Zp8.
To use the pack pragma to specify packing other than the packing
specified on the command line for a particular structure, give the pack
pragma, where the packing size is 1, 2, 4, 8, or 16, before the
structure. To reinstate the packing given on the command line, specify
the pack pragma with no arguments.
Bit fields default to size long for the Microsoft C compiler. Structure
members are aligned on the size of the type or the /Zp[n] size, whicheve=
r
is smaller. The default size is 4.
END Microsoft Specific
---- Quote stop ----
2 Win32 header files should give you all you need:
<windef.h> mostly and some in <basetsd.h>
Examples:
offsetof is a c macro defined as:
#define offsetof(type, member) ((std::size=5Ft)) &(((type*) 0)->member))=
It returns the address of a member for a struct whose address is zero.
struct C2F
{
BYTE f1;
WORD f2;
};
offsetof(C2F, f2) =3D 2.
struct C2F
{
BYTE f1;
DWORD f2;
};
offsetof(C2F, f2) =3D 4.
struct C2F
{
BYTE f1;
BOOL f2;
};
offsetof(C2F, f2) =3D 4.
struct C2F
{
BYTE f1;
DOUBLE f2;
};
offsetof(C2F, f2) =3D 8.
sizeof(char) =3D 1
sizeof(short) =3D 2
sizeof(int) =3D 4
sizeof(long) =3D 4
sizeof(float) =3D 4
sizeof(double) =3D 8
sizeof(BYTE) =3D 1
sizeof(WORD) =3D 2
sizeof(DWORD) =3D 4
sizeof(LPARAM) =3D 4
(unsigned equivalents have identical size).
I am using a human parser here... If you need more info or some simple
compiler verifications on specific struct(s), I'd be happy to help.
Sincerely,
Conrad Weyns.
>
>Could anyone point me to a resource that details some of the fine
>points of C structures and how a C compiler interprets these
>structures=3F
>
>Best Regards, Mike Ghan mikeghan_at_logix-controls.com
>
>Logix Industrial Control Systems http://www.logix-controls.com
>10518 NE 68th St
>Kirkland, WA 98033 USA
>(425)828-4149 (425)828-9682 Fax
>
>----------------------------------------------------------------------
>sftalk_at_forth.com The SwiftForth programming discussion email list
>To unsubscribe, send subject "unsubscribe sftalk" to listar_at_forth.com
>For help with listar commands, send subject "help" to listar_at_forth.com
>Archives are located at http://www.forth.com/sftalk -- check them out!
>
>
----------------------------------------------------------------------
sftalk_at_forth.com The SwiftForth programming discussion email list
To unsubscribe, send subject "unsubscribe sftalk" to listar_at_forth.com
For help with listar commands, send subject "help" to listar_at_forth.com
Archives are located at http://www.forth.com/sftalk -- check them out!
----------------------------------------------------------------------
sftalk_at_forth.com The SwiftForth programming discussion email list
To unsubscribe, send subject "unsubscribe sftalk" to listar_at_forth.com
For help with listar commands, send subject "help" to listar_at_forth.com
Archives are located at http://www.forth.com/sftalk -- check them out!
Received on Mon Apr 16 2001 - 06:09:19 PDT
Subscribe to our e-mail list service. It's free for all SwiftForth and SwiftX users!
This archive was generated 09-Feb-2012. Archive updated nightly.