[comp.lang.lisp] foreign functions to KCL

bouma@cs.purdue.EDU (William J. Bouma) (11/10/88)

We would like to call functions from KCL that are compiled into some library.
How can we get these functions loaded into the lisp environment? 
It seems like it should be possible to link them in at some time when the
KCL is compiling and loading C. Anyone done this before?

-- 
Bill <bouma@cs.purdue.edu>  ||  ...!purdue!bouma 

whaley@june.cs.washington.edu (Ken Whaley) (11/10/88)

The good news is that it's easy to incorporate C functions into
KCL.  The bad news is that unless you want to write C code that can't
be used outside of the KCL environment, then you are constrained to use
certain input parameter and function return types.  I don't purport to be an
expert on KCL -- this is just what I figured out from playing around with the
system.  By the way, I'm working with the "June 3, 1987" version of KCL.

As an example of how to use C code from KCL, let's write the square function
(that takes an integer argument and returns its square) in C, and foreign
function it into KCL.

Let's call the C function "c_square", and the LISP function "square".

:NOTE:  
The KCL documentation says that the following is specific to the BSD version
of KCL.

1. Create a file called "square.lsp" that consists of the line:

	(defentry square (int) (int c_square))
Argument 1 type------------^
Return type----------------------^
Name of C function in C source file-----^

(Other types that I know work are: char, double.  I imagine that any
"one-work" type should work.

2. Create the C file, say c_square.c:
	
	int c_square (x) int x; { return (x * x); } 

3. In KCL, type (compile-file "square").

4. Compile the C file from the shell (cc -c -O c_square.c)

5. In KCL, now type (si:faslink "square.o" "c_square.o")

6. You're in business.

	(square 7) ==> 49

	Note that the second string in step 5 is passed
	directly to "ld", so you can include other libraries (I don't believe
	that the C library is automatically included for you, so if you use
	any C library routines, you'll have to write the following
	for step 5): (si:faslink "square.o" "c_square.o -lc").

BTW, this information in included in the "doc/kclunix" file of the KCL
distribution.

Oh, and I've only managed to get this working with non-pointer types.
I haven't experimented with structs, either.  You can pass in, manipulate,
and return arbitrary LISP objects (KCL itself is written in C....), but
that sort of information is, as far as I know, undocumented, and you'd
have to dig through the source code to figure it out.

			Ken

						     
-- 
whaley@june.cs.washington.edu

jeff@aiva.ed.ac.uk (Jeff Dalton) (11/16/88)

In article <6381@june.cs.washington.edu> whaley@uw-june.UUCP (Ken Whaley)
writes:
>The good news is that it's easy to incorporate C functions into
>KCL.  The bad news is that unless you want to write C code that can't
>be used outside of the KCL environment, then you are constrained to use
>certain input parameter and function return types.

That's more or less true if you want to return something to be manipulated
in Lisp -- it has to be one of the objects Lisp knows about.  However, you
can malloc things, define (Lisp) procedures that call C procedures to
manipulate such objects, and so on.  It's just that there isn't a "C
structure" facility built-in.

>:NOTE:  The KCL documentation says that the following is specific
> to the BSD version of KCL.

I think only some it it (such as si:faslink) is just for BSD.  But since
I almost always use BSD I can't say for sure that it works.  Nonetheless,
since KCl compiles to C, some kind of C interface is surely possible.

>Oh, and I've only managed to get this working with non-pointer types.
>I haven't experimented with structs, either.  You can pass in, manipulate,
>and return arbitrary LISP objects (KCL itself is written in C....), but
>that sort of information is, as far as I know, undocumented, and you'd
>have to dig through the source code to figure it out.

Basically, Lisp objects are pointers to a union of structs.  So each
Lisp object corresponds to some C struct.  The structs, union, etc.
are defined in object.h and the subset used by compiled code is in
cmpinclude.h.

-- Jeff

alex@umbc3.UMD.EDU (Alex S. Crain) (11/20/88)

In article <6381@june.cs.washington.edu> whaley@uw-june.UUCP (Ken Whaley)
writes:
>The good news is that it's easy to incorporate C functions into
>KCL.  The bad news is that unless you want to write C code that can't
>be used outside of the KCL environment, then you are constrained to use
>certain input parameter and function return types.

	One way to add C code to kcl is to build an interface library of
empty functions in lisp, ie:

	(defun c-fun-1 (arg1 arg2) nil)
	(defun c-fun-1 (arg1) nil)

and then compile this into C. the result is a file full of empty C functions
with all the appropriate argument tags. Then backfill the C code with your 
funcions and compile/load that. This doesn't require si:faslink (which I don't
have anyway) and does all your argument handling for you.

-- 
					:alex.
					Systems Programmer
nerwin!alex@umbc3.umd.edu		UMBC
alex@umbc3.umd.edu