` Printed Icetips Article

Icetips Article



Windows API: Enumerating Fonts and discussion about memory
2003-05-05 -- Larry Sand
 
Newsgroups: softvelocity.products.c55ee


Maarten wrote:
| I'm trying, I'm trying
| I can read the code and see what it does.
| The 'understanding' part will come eventually
|
| What I mean by this is that I can read and understand the
| code you posted but when I had to write it myself I
| would not have found this solution (i.e. getting a pointer
| to a block of memory back from the API and then use
| MoveMemory to write that directly to the memory space,
| reserved by the fontsque-buffer).

Hi Maarten,

I understand completely! ;)


I know that you understand most of this, but let me try to explain.  Whenever the
documentation states something to the effect that a parameter returns a pointer to a
structure; you must find a way to dereference that pointer in Clarion.  In C you declare
it as a pointer and then use the appropriate syntax to read the elements of the
structure.

However, Clarion doesn't have any formal pointer data types.  There are reference
variables, but in most instances they are more than just a pointer.  For simple data
types, reference variables are just a pointer, but for strings and groups they are
compound structures.

For the rest of this message, I'll use "pointer" and "address of" interchangeably even
though they're not equivalent in the C sense.

Say you have a structure (group) declared like this:

MyGroupType  GROUP,TYPE
long1               LONG
long2               LONG
short1              SHORT
short2              SHORT
            END

You've told the compiler what the group looks like, but there's no memory allocated.
So declare a group like the one just declared.

MyGroup LIKE(MyGroupType)

When the program runs, it allocates some memory that you can refer to with the label
MyGroup.  Right?  MyGroup symbolically represents some address in memory when the
program's running.  It's the address of the first byte of the group.  So, when you write,
MyGroup.long2 you're really asking for contents of the four bytes of memory at
ADDRESS(MyGroup)+4.

Now, back to the function that returns a pointer to a structure.  Assume that you have a
function that returns a pointer to a MyGroupType structure.  What is this pointer?  It's
the address of the first byte of the structure.  So how do you get that into Clarion?
Sometimes you'll see code that does this:

MyGroupRef    &MyGroupType

Now you have a reference variable for a MyGroupType.  Remember that the reference
variable
doesn't allocate any memory for the actual group, it is only the memory for the reference
variable.

MyGroupRef &= (PointerToAMyGroupTypeStructure)

The parenthesis fool the compiler into thinking it's a function.

Then you can access the elements of the group using normal dot notation.  For example:
MyGroupRef.short1.  And it works.  However, all you've done is to fill the pointer
portion
of the group reference.  I don't recommend this because you may be tempted to use this as
a valid Clarion reference variable.

Instead I recommend that you use one of the functions to copy the memory into memory that
Clarion knows about.  Going back to the definition of MyGroup:

MyGroup LIKE(MyGroupType)

Now there's some memory allocated the size of MyGroupType.  This group is identical to
the
one you have the address of stored in PointerToAMyGroupTypeStructure.  To access the
elements using standard dot notation, you must make a copy.  To do this you can use any
of
the standard C library (like _memcpy) or exported Windows API copy (like RtlMoveMemory)
functions.

Using MoveMemory, you copy the SIZE(MyGroup) source bytes from the
address(PointerToAMyGroupTypeStructure) to the destination address (ADDRESS(MyGroup)).

MoveMemory(MyGroup, PointerToAMyGroupTypeStructure, SIZE(MyGroup))

Now you have an exact copy in the memory that Clarion knows how to access with standard
dot notation.


HTH,
Larry Sand



Printed May 7, 2024, 3:36 am
This article has been viewed/printed 35119 times.
Google search has resulted in 37 hits on this article since January 25, 2004.