From: One
Subject: Foreign function calls
Date: 
Message-ID: <8671b9$udu$1@news5.svr.pol.co.uk>
I have been trying to use the "foreign function" package in Allegro CL
Personal Ed on Windows98.  (This is not an MS Windows specific question.)  I
cannot work out how to pass a pointer (e.g. to a struct) to a
"def-foreign-call"ed C function.  I have seen the example in the
documentation that uses an array of one element and have tried to replicate
it for the function GetCursorPos() in user32.dll which requires a pointer to
a windows POINT.


For those who do not use the Windows API the prototype for this function is:

     BOOL GetCursorPos(
       LPPOINT lpPoint   // address of structure for cursor position
     );

and POINT is:

     typedef struct tagPOINT

         LONG x;
         LONG y;
     } POINT;

BOOL and LONG are both signed 32 bit integers.


My attempt looks like this:

     (ff:def-foreign-type win-pt (:struct (x :int) (y :int)))

     (ff:def-foreign-call (get-mouse "GetCursorPos") ((simple-array win-pt))
:returning :int)

     (defparameter pt (ff:allocate-fobject 'win-pt))
     (defparameter ptr-to-pt (make-array 1 :element-type 'win-pt))

This is the result:

     > (setf (aref ptr-to-pt 0) pt)
     #<foreign object of class WIN-PT>

     > ptr-to-pt
     #(#<foreign object of class WIN-PT>)

     > (get-mouse ptr-to-pt)
     33

     > ptr-to-pt
     #(#<unknown object of type number 3 @ #x20b>)

     > pt
     #<foreign object of class WIN-PT>

As you can see, the call to get-mouse has mangled the single element of
ptr-to-pt.  pt is still intact.


I know that this function is in the "windows" package in Allegro but it is
the foreign call syntax that I am trying to work out.  Interestingly the
"windows" package version of this function uses a type "position" from the
"common graphics" package but the struct (class?) definition is not
documented, just its accessors and a make-position function.

Justin Hellings
XWare
From: Jason Kantz
Subject: Re: Foreign function calls
Date: 
Message-ID: <38934E5C.9A62F2AF@kantz.com>
The franz documentation isn't the easiest to understand.

I've done something like this ..

(def-foreign-type gdPoint
    (:struct (x :int)
             (y :int)))

Then to make an array of these points, I do this within a macro that
builds the array.

`(allocate-fobject '(:array (:struct (x :int) (y :int)) ,(/ (length xys)
2)) :c)

To build the elts I access the foreing array w/ 
(setf (fslot-value-tyepd (:array (:struct (x :int) (y :int)) ...

Then I pass the address of the first elt of the array, accessed w/
fslot-address-typed,
to the lisp foreign function.



One wrote:
> 
> I have been trying to use the "foreign function" package in Allegro CL
> Personal Ed on Windows98.  (This is not an MS Windows specific question.)  I
> cannot work out how to pass a pointer (e.g. to a struct) to a
> "def-foreign-call"ed C function.  I have seen the example in the
> documentation that uses an array of one element and have tried to replicate
> it for the function GetCursorPos() in user32.dll which requires a pointer to
> a windows POINT.
> 
> For those who do not use the Windows API the prototype for this function is:
> 
>      BOOL GetCursorPos(
>        LPPOINT lpPoint   // address of structure for cursor position
>      );
> 
> and POINT is:
> 
>      typedef struct tagPOINT
> 
>          LONG x;
>          LONG y;
>      } POINT;
> 
> BOOL and LONG are both signed 32 bit integers.
> 
> My attempt looks like this:
> 
>      (ff:def-foreign-type win-pt (:struct (x :int) (y :int)))
> 
>      (ff:def-foreign-call (get-mouse "GetCursorPos") ((simple-array win-pt))
> :returning :int)
> 
>      (defparameter pt (ff:allocate-fobject 'win-pt))
>      (defparameter ptr-to-pt (make-array 1 :element-type 'win-pt))
> 
> This is the result:
> 
>      > (setf (aref ptr-to-pt 0) pt)
>      #<foreign object of class WIN-PT>
> 
>      > ptr-to-pt
>      #(#<foreign object of class WIN-PT>)
> 
>      > (get-mouse ptr-to-pt)
>      33
> 
>      > ptr-to-pt
>      #(#<unknown object of type number 3 @ #x20b>)
> 
>      > pt
>      #<foreign object of class WIN-PT>
> 
> As you can see, the call to get-mouse has mangled the single element of
> ptr-to-pt.  pt is still intact.
> 
> I know that this function is in the "windows" package in Allegro but it is
> the foreign call syntax that I am trying to work out.  Interestingly the
> "windows" package version of this function uses a type "position" from the
> "common graphics" package but the struct (class?) definition is not
> documented, just its accessors and a make-position function.
> 
> Justin Hellings
> XWare

-- 
Jason Kantz
http://kantz.com/jason