Structures


Many Win32 functions require the use of structures and I have developed my own system for creating & accessing structures. It may not be pretty OR safe but it is fast. A necessary part of using structures is allocating & releasing small blocks of memory. This is a (relatively) time consuming exercise. On my P150 I get 14.3 seconds using allocate() & free() for 1,000,000 small blocks of memory ~ 70k/s. However, where possible I am directly reusing the structure memory for an associated function within a management routine. This can significantly boost the performance of the routine since the overhead of extra allocate() & free() calls is avoided. I have now started using a permanently allocated RAM scratchpad for some functions which (i) could be called a lot and (ii) I would not expect to be interrupted by another call which would use (therefore corrupt) the same memory. In some instances I am getting 1.26 seconds ~ 790k/s. In the case of allocating & pokeing null terminated text strings the result is 3.42 seconds ~ 290k/s and is 4 times faster than allocate_string() & free() but, of course, without any safety barrier (other than the size of the buffer) to prevent corruption of the referenced memory.

Although only a small number of structures (approx. 25) have been defined in structures.ew I think the library is still quite capable for many purposes. I will add more structure definitions as time goes on and the need for them becomes apparent.

Structure definitions can ONLY be added to this file since the functions to create them are local to that include file. Additional structures can be defined in 2 easy steps: --
step 1) define the name of the structure as a constant. I always use the Win32 API names.eg:

constant
    RECT = new_struct(),
step 2) define the individual elements of the structure as constants. Note the Structure name is prefixed to the member names. A bit verbose but safe.

    RECT_left = struc(C_LONG),
    RECT_top = struc(C_LONG),
    RECT_right = struc(C_LONG),
    RECT_bottom = struc(C_LONG)
The parameter in the struc() function can be ANY predefined structure name or the usual structure constants as defined in dll.e Now, the structure name (RECT) has become an index to my structure list but the elements are actually displacements relative to the first element. ONLY these displacements can be used later on when accessing the structure.

To ascertain the size of the structure in bytes simply call sizeofstruct(STRUCTNAME), eg:

    lpRect = allocate( sizeofstruct( RECT ) )
This size value is needed when allocating memory to poke a structure into memory or alternatively when reserving space for a Win32 API function to use. Later structures may now be defined incorporating the earlier ones, eg:

    -- Define PAINTSTRUCT Structure
    PAINTSTRUCT = new_struct(),
    PAINTSTRUCT_hdc = struc(C_LONG),
    PAINTSTRUCT_fErase = struc(C_SHORT),
    PAINTSTRUCT_rcPaint = struc(RECT), -- ***** note the use of RECT here!!
    PAINTSTRUCT_fRestore = struc(C_SHORT),
    PAINTSTRUCT_rgbReserved = struc(anySize(32)),
Please ensure that the minor structures are completed BEFORE incorporating them into a larger structure. You will note a function called anySize() which can be used to reserve an arbitrary number of bytes in the structure; 32 in the example above. Access to structures is simply a matter of peeking or pokeing the desired structure member, eg:

    ps = allocate(sizeofstruct(PAINTSTRUCT))
    -- do some code
    rFlag = peek4u(ps + PAINTSTRUCT_fRestore)
    -- rFlag now has the value of the Restore flag
PLEASE NOTE that although the size in bytes of each structure member seems to be recorded in the structure list, in reality no error checking is done on the size of the peeked or poked value so the user is cautioned to be very careful when accessing the structure. Another trap is the fact that where minor structures are incorporated in other structures then the user has to allow for accessing the deeper structure, ie if the user wanted to access the RECT_top member of the RECT structure embedded in PAINTSTRUCT structure then they would have to do so explicitly, eg:

    top = peek4u(ps + PAINTSTRUCT_rcPaint + RECT_top )
Care must be made when accessing the, by now, somewhat rare WORD (16-bits) fields since Euphoria has no native access to this type. But really, how difficult would it be to add your own peek2() functions. If you use meditor then it is a cinch to allow syntax coluring to make it quite easy to spot typing errors for those new routines that you might make. [Update - I have now added poke2(), peek2s() & peek2u() to structures.ew] There is a distinct lack of error checking in the structures section because I am chiefly concerned (some might say obsessed) with performance. By using verbose member designations I have had little problem accessing the correct elements.