define_struct
Definition: |
include cffi.e object x = define_struct(string struct_str, integer machine=machine_bits(), bool bAdd=true) |
Description: |
parse a C struct definition into sizes/offsets etc.
Note: This functionality is now wrapped by c-struct, which you may find slightly easier to use, however that will not play nice with any embedded TCHAR[] or similar fields. |
pwa/p2js: | Not supported. |
Comments: |
The struct_str parameter is text copied from a C header file - note that without a "typedef", nothing gets stored permanantly. The machine parameter can be set to 32 or 64, for testing purposes. The bAdd parameter can be set to false for testing (override/ignore "typedef") If struct_str begins #pragma pack(1) the usual padding to 2/4/8 byte boundaries is not performed (32-bit only).This has been specifically added to cope with commdlg.h which contains
hence that pragma (currently) only applies under 32-bit. No other variant of pragma pack is [yet] supported. If bAdd is true and struct_str contains "typedef", the return value is a small integer id that can be used in calls to allocate_struct(), set_struct_field(), get_struct_field(), get_field_details() and get_struct_size(). Otherwise the full details of the structure are returned, which you can display, use to write a little help file, or perhaps even directly use the sizes and offsets etc. Typically this is only useful for testing/diagnostic purposes, see the dropdown below for more info. The struct definition may contain comments, however they must be C-style, ie/eg // comment or /* comment */ ,
and not -- comment .
|
Example 1: |
include cffi.e constant tMBP=""" typedef struct { UINT cbSize; HWND hwndOwner; HINSTANCE hInstance; LPCTSTR lpszText; LPCTSTR lpszCaption; DWORD dwStyle; LPCTSTR lpszIcon; DWORD_PTR dwContextHelpId; MSGBOXCALLBACK lpfnMsgBoxCallback; DWORD dwLanguageId; } MSGBOXPARAMS, *PMSGBOXPARAMS; """ constant integer idMBP = define_struct(tMBP) |
Example 2: |
include cffi.e constant tRECT = """ typedef struct _RECT { LONG left; LONG top; LONG right; LONG bottom; } RECT, *PRECT;""", tPS = """ typedef struct tagPAINTSTRUCT { HDC hdc; BOOL fErase; RECT rcPaint; BOOL fRestore; BOOL fIncUpdate; BYTE rgbReserved[32]; } PAINTSTRUCT, *PPAINTSTRUCT;""", idRECT = define_struct(tRECT) idPS = define_struct(tPS) Structures can be nested - tPS can use "RECT", but only after tRECT has been processed. NB: in tRECT, _RECT is discarded/replaced by RECT. Had that struct ended with "};" then _RECT would have been kept, and RECT (etc) ignored. The "sequence structs" in cffi.e currently holds only one name per struct. (see notes therein) In contrast, pointer names such as PRECT are (all) kept separately, albeit to cffi.e they are just pointers that would explicitly need the correct id (eg/ie idRECT) to delve any deeper. Note there is no "rcPaint", instead we have "rcPaint.left" etc. |
Bitfields: |
Note that cffi.e does not (yet) support bitfields, for exampleinclude cffi.e constant tDCB = """ typedef struct _DCB { DWORD DCBlength; DWORD BaudRate; DWORD fBinary : 1; DWORD fParity : 1; DWORD fOutxCtsFlow : 1; DWORD fOutxDsrFlow : 1; DWORD fDtrControl : 2; DWORD fDsrSensitivity : 1; DWORD fTXContinueOnXoff : 1; DWORD fOutX : 1; DWORD fInX : 1; DWORD fErrorChar : 1; DWORD fNull : 1; DWORD fRtsControl : 2; DWORD fAbortOnError : 1; DWORD fDummy2 : 17; WORD wReserved; WORD XonLim; WORD XoffLim; BYTE ByteSize; BYTE Parity; BYTE StopBits; char XonChar; char XoffChar; char ErrorChar; char EofChar; char EvtChar; WORD wReserved1; } DCB, *LPDCB;""", idDCB = define_struct(tDCB) fails with the (somewhat obtuse) error "bitfields are not (yet) supported". In this particular case, the 32 bits of fBinary .. fDummy2 are packed into a single 32-bit dword, but note should the :1 .. :17 over-run it ought to allocate further dwords as needed - if you encounter an example that does that, or slices byte/word[s]/etc let me know, ideally along with something I can properly test. It would (probably) not be particularly difficult to extend cffi.e to cope (eg -ve offset/size/signed), but for now you should replace those 14 fields with a single dword and perform the necessary bit-slicing on that yourself, again let me know should that start getting too tedious or too error-prone. |
See Also: | allocate_struct, set_struct_field, get_struct_field, get_field_details, set_unicode, machine_bits |
