Path: utzoo!utgpu!water!watmath!clyde!att!osu-cis!tut.cis.ohio-state.edu!mailrus!ames!lll-tis!helios.ee.lbl.gov!pasteur!ucbvax!decwrl!sun!pitstop!sundc!seismo!uunet!mcvax!ukc!etive!aiva!jeff
From: jeff@aiva.ed.ac.uk (Jeff Dalton)
Newsgroups: comp.lang.lisp
Subject: Re: Calling C functions from Franz Lisp
Message-ID: <484@aiva.ed.ac.uk>
Date: 5 Jul 88 18:25:47 GMT
References: <12196@sunybcs.UUCP>
Reply-To: jeff@uk.ac.ed.aiva (Jeff Dalton)
Organization: Dept. of AI, Univ. of Edinburgh, UK
Lines: 91

In article <12196@sunybcs.UUCP> jagota@sunybcs.uucp (Arun Jagota) writes:

>I AM HAVING PROBLEMS IN PASSING BACK THE LIST I CREATE IN THE C
>FUNCTION.

I can give a more or less complete answer to your question but don't
have time to do it today.  I'll send this in the hope that it's some
help and try to say more if it appears that no one else has already
covered everything.

>Lisp format in C that I use (As documented in the Franz Lisp manual).
>
>struct lisplist 
>  { struct lisplist *cdr;
>    int 	     car;
>   }

OK, the first thing to not is that this isn't the real definition
of Lisp data used by the Franz system.  For some purposes, you need
the real definition in `franz/h/global.h' in the Franz source
directory.  To access it, use -I with cc.  A makefile makes this
easier.  However, you may be able to avoid this.

>My C function then creates a list as follows.

>struct lisplist *temp,*current;
>char *word;
>
>temp = (struct lisplist *) malloc(sizeof(*temp));
>temp->car = (int) word;
>temp->cdr = current;
>current = temp;

This is where the problems come in.

(1) In many versions of Franz, you may not be able to use malloc
without confusing Lisp.  I've never actually used malloc, though,
so I am not sure of this.  The reason I don't use malloc is:

(2) Franz determines the type of an object by looking at the
high-order bits of its address.  It divides memory into (logical)
pages where each page contains objects of a single type.  The high
order bits give the page, and then there's a table giving the type of
each page.  So, in order to allocate a cons cell (what Franz calls a
dtpr (dotted pair), you can't just allocate it anywhere: you have to
allocate it on a cons cell page.  The same applies to strings: they
must be allocated on string pages.  Of course, you can still make
pointers to randon storage, but problems may appear later if Lisp ever
wants to check the object's type.

Unfortunately, I can't tell you how to create Lisp objects in C
because, without writing some code, I can't be sure just how much
I'll have to tell you about.  (I do have code that does this sort
of thing, but I'm hoping to avoid describing everything it does.)

(3) You don't say how you actually return the list.  Remember that
your C function has to be made known to Lisp (with getaddress, say)
and have discipline "function".  Then you can just return the pointer
to the start of the list in the usual C way (modulo the problems
mentioned above).

What it comes down to is that it is a pain to write C code that
creates Lisp data.  In addition to the things already mentioned, you
may have to worry about garbage collection (if you allocate a Lisp
object, the garbage collector may be called).  Consequently, you may
want to protect objects from collection, and that brings you into
contact with Franz internals that you may not want to know about.

Other things:

>I'm running this on a Vax 11-785 running Unix 4.3 BSD.

What version of Franz are you using?

>Most of my C functions retrieve certain words from the data base,
>create a list (in lisp format) to store them and pass them back to 
>the lisp program that called the C function. 

You might want to consider a different organization of your program.
You could have a C function that acted as a generator.  It would pass
back the next item each time called, and the Lisp code that called it
could build the list.  Of course, this may not be easy to do, but
often it is (you have to keep track of some state in the C code).

Another approach is to preallocate a list amd pass it to your
C code.  It is much easier to modify existing data than to create
new data.

Jeff Dalton,                      JANET: J.Dalton@uk.ac.ed             
AI Applications Institute,        ARPA:  J.Dalton%uk.ac.ed@nss.cs.ucl.ac.uk
Edinburgh University.             UUCP:  ...!ukc!ed.ac.uk!J.Dalton