dickinsn@cs.unm.edu (Emily G. Dickinson) (05/09/91)
I'm using allegrom cl on SUN4 and would appreciate sample code from anyone who has succeeded in calling lisp functions from C programs. Thanks, Emily Dickinson, University of New Mexico
rbj@uunet.UU.NET (Root Boy Jim) (05/10/91)
dickinsn@cs.unm.edu (Emily G. Dickinson) writes:
?I'm using allegrom cl on SUN4 and would appreciate sample
?code from anyone who has succeeded in calling lisp
?functions from C programs.
I think that I shall never see
a LISP function that's called from C.
?Thanks,
?Emily Dickinson, University of New Mexico
--
[rbj@uunet 1] stty sane
unknown mode: sanerapo@cs.cornell.edu (Andy Rapo) (05/10/91)
Emily,
I've been doing a lot of C/Lisp interfacing lately with
allegro. In order to call a lisp function from C, you need to load
the C code into your lisp image. Then you need to make your lisp
functions c-callable and register them with Lisp. Lisp stores a
pointer to the function in a table that C can access. If the
registered Lisp function moves, the pointer in the table is updated.
In this way, C can always find the Lisp function.
(defun-c-callable scale_z-callback (val)
(format t "This is Lisp called with value ~A. ~%" val))
(multiple-value-setq (*ptr1* *index1* *prev-ptr1*)
(register-function 'scale_z-callback))
*ptr1* is a pointer to the Lisp function. *index1* is an index into
the table of pointers. I haven't used *prev-ptr1* yet. *ptr1* is the
value you need for now.
You have to pass C the address of the Lisp function that you want to
call. The way I have done this is to set up a structure in C
that holds poiters to functions. In C the struct looks like this:
/* these are all pointer to functions that return int */
typedef struct ptr_type {
int (*scale_z)();
int (*scale_y)();
int (*scale_x)();
.
.
.
} ptr_type;
ptr_type ptr;
This C code would be in a file like c-interface.c. This file would be compiled and the resulting object file, c-interface.o, would be loaded into Lisp. More on this in a sec.
In order to assign values to members of the struct I make the struct
accessible to Lisp using the defcstruct function. This function makes
accessor functions for a c-struct.
;;; MAKE-PTR-STRUCT-ACCESSORS makes accessor functions which, when
;;; supplied with a pointer to a C struct, will return the value
;;; stored there. Setf can be used to modify the C struct. The C
;;; struct exists in C space and is not moved by Lisp garbage collection.
(defun make-ptr-struct-accessors ()
(defcstruct (ptr :malloc)
(scale_z :unsigned-long)
(scale_y :unsigned-long)
(scale_x :unsigned-long)
.
.
. ))
Then I can get the value of a c-struct member (i.e. scale_z) by typing
(ptr-scale_x *pointer-to-cstruct*).
These are like CLOS accessors.
I have to supply a pointer to the (ptr-scale_z ...)
function so that Lisp can find the c-struct. In C, I've defined the
following function which returns the address of the c-struct.
ptr_type *get_ptr_address()
{
return &ptr;
}
I make this function (and the other C objects I need) available to Lisp by loading the .o file that it is defined in.
(load "" :foreign-files '("c-interface.o")
:system-libraries '("m" "gl_s"))
Next I make Lisp aware of the newly loaded c function.
(defforeign 'get_ptr_address :arguments nil
:return-type :integer))
And then I call the c function, get_ptr_address, to get the address of
the c-struct, *ptr*, and use it with the Lisp accessor functions to get at the values of the c-struct.
;;; SET-PTR-STRUCT-ADDRESS sets *ptr* to be the address of the C
;;; struct which contains pointers to Lisp functions.
;;; These pointers are used by C to "callback" to Lisp.
(defun set-ptr-struct-address ()
(setf *ptr* (get_ptr_address)))
(defun set-callback-ptrs ()
(setf (ptr-scale_z *ptr*) *ptr1*))
Now, the c-struct member, ptr.scale_z, contains *ptr1* which is the
address of the Lisp function, scale_z-callback.
C can call this Lisp function like this:
(*ptr.scale_z)(val);
Whew....
Well, its actually very easy to do, and worth the effort. Interfacing
between C and Lisp can make life very easy for you later on. If you
have any questions let me know. As I said, I've been doing this a lot
lately and would be glad to share what I've learned.
Andrew Rapo
Cornell University
Simulation/Roboticsgold@sgi.com (Michael Gold) (05/11/91)
In article <132261@uunet.UU.NET> rbj@uunet.UU.NET (Root Boy Jim) writes: >I think that I shall never see >a LISP function that's called from C. > Perhaps somebody can clarify this point, but I believe you *can* call a lisp function from C, assuming the C function is called from the lisp process... -- Michael I. Gold You go your way, I'll go mine, Silicon Graphics Inc. I don't care if we get there on time, Internet: gold@sgi.com Everybody's searching for something they say, Voice: (415) 335-1709 I'll get my kicks on the way...
cccstevn@dino.ucdavis.edu (Steve Ansell) (05/11/91)
In article <1991May10.202942.1569@odin.corp.sgi.com> gold@sgi.com (Michael Gold) writes: >In article <132261@uunet.UU.NET> rbj@uunet.UU.NET (Root Boy Jim) writes: >>I think that I shall never see >>a LISP function that's called from C. >> > >Perhaps somebody can clarify this point, but I believe you *can* call a >lisp function from C, assuming the C function is called from the lisp >process... > I beleive that this posting was in response to the fact that the person who asked the original question about calling Lisp from C had a signature of "Emily Dickinson". The above is a parody of one of her poems. In other words it was a joke ;-) -- -Steven T. Ansell Unix Consultant Computing Services U.C.D.
gold@sgi.com (Michael Gold) (05/12/91)
In article <12931@aggie.ucdavis.edu> cccstevn@dino.ucdavis.edu (Steve Ansell) writes: >I beleive that this posting was in response to the fact that the person who >asked the original question about calling Lisp from C had a signature of >"Emily Dickinson". The above is a parody of one of her poems. In other >words it was a joke ;-) > Sorry, I only open my mouth to change feet. :-q -- Michael I. Gold You go your way, I'll go mine, Silicon Graphics Inc. I don't care if we get there on time, Internet: gold@sgi.com Everybody's searching for something they say, Voice: (415) 335-1709 I'll get my kicks on the way...
dak@sq.sq.com (David A Keldsen) (05/14/91)
cccstevn@dino.ucdavis.edu (Steve Ansell) writes: >In article <1991May10.202942.1569@odin.corp.sgi.com> gold@sgi.com (Michael Gold) writes: >>In article <132261@uunet.UU.NET> rbj@uunet.UU.NET (Root Boy Jim) writes: >>>I think that I shall never see >>>a LISP function that's called from C. >>Perhaps somebody can clarify this point, but I believe you *can* call a >>lisp function from C, assuming the C function is called from the lisp >>process... >I beleive that this posting was in response to the fact that the person who >asked the original question about calling Lisp from C had a signature of >"Emily Dickinson". The above is a parody of one of her poems. In other >words it was a joke ;-) Unfortunately, the parodied poem is by...Joyce Kilmer. Yet another example of a beautiful hypothesis slain by an ugly fact. ;-) (There should be an example in the manual on how to call Franz Lisp functions from C; alas, it has been many a year since I saw the manual, and my recollection is foggy...roughly, you need to get back in to the "Franz machine" (via a function call) with a representation of a Lisp function, its arguments, and the appropriate environment.) (The LISP creeps in on little cat's parentheses...) [Well, Robert Frost also lived in Amherst, Massachusetts, so it's a bit closer.] Dak -- David A. 'Dak' Keldsen of SoftQuad, Inc. email: dak@sq.com phone: 416-963-8337 "You'd better get on with it," she said. "That's fifty green fires and hot leads to go, with a side order for blisters and scorpions. Hold the mercy." -- _Sourcery_ by Terry Pratchett