[Ecls-list] using built library files in C program

Michael Hannemann hannemann at inetmi.com
Fri Apr 4 12:58:02 UTC 2003

Juan Jose Garcia Ripoll replies:
>On Tuesday 01 April 2003 01:18, Michael Hannemann wrote:
> > Following the steps in the developer's guide, it seems like I should be
> > quite close.  I've been able to copy the stand-alone executable to another
> > system and watch it run.  (2.5MB!  Much smaller than ACL or
> > Lispworks.)  I've produced a .a file, and I've looked at the temporary .c
> > and .h files.  But it seems like there's crucial interface information
> > missing; I suspect I could call the munged and re-defined C functions L1
> > (L2, &c.), but is there an easier way?
>Have you considered using cl_funcall(), cl_apply() and c_string_to_object()?
>With s = c_string_to_object("FIB") you obtain the symbol for your function
>(assuming that the library has been initialized before). With cl_funcall(2,
>s, MAKE_FIXNUM(2)), you use your function.

If by "considered using" you mean "realized the existence of", no, I 
hadn't, but I have now.  =)  There are enough unknowns for me, though, that 
I'm going to post a little code in the hopes that you can immediately tell 
me what I'm doing wrong.

>The only problem is initialization. Lisp libraries have to be initialized in
>an order which corresponds to the order in which the would be loaded if they
>were *.lsp files. ECL takes care of this when building executable programs:
>build-program produces the right sequence of C statements for that. If you do
>not want to use ECL to link the files, then I am afraid you will have to
>inspect the output of build-program and reproduce it yourself.

When you say "inspect the output of build-program", do you mean at the 
level of "look at what gcc commands ECL produces", or "look at the 
init_CODE block in the temporary .h file and use that somehow"?

>Sorry, I know the interface is quite ugly, but I am very busy fixing errors in
>the lisp part :-)

I'm all for fixing the lisp errors!  If I seem at all frustrated, it's 
because the ECL examples _almost_ speak to my task directly, but then stop 
short.  If only they went a teensy bit farther...  =)

So, I can build a shared library out of sample lisp code; it's 32 KB, and 
can be loaded into ECL.  That's step one.

Examining the way (c:build-program) compiles and links things together, my 
makefile executes:

gcc -g -O2 -fstrict-aliasing -Dlinux -O -I/usr/local/lib/ecl/lib/ecl/h  -w 
-c test.c -o test.o

gcc -w -o testapp test.o -L. -lfactlib -L/usr/local/lib/ecl/lib/ecl/ -lecl 
-lclos -llsp -lgmp -Wl,--export-dynamic -lgc -ldl -lgmp -lm

(where fact.* is lisp factorial code for testing, and test.* is C code 
which wants to call lisp code).

The actual text of test.c is appended below.  Compiling and linking 
succeed, and the executable _is_ the size I would expect, about 
2.5MB.  I've gone through several variations, including loading the 
intermediate header files in the test.c, and calling or not calling the 
init_CODE function produced in that header file, but all attempts segfault 
on the first lisp call (whatever that happens to be).

I suspect something braindead is going on.

thanks for reading,


#include <stdio.h>
#include <ecl-cmp.h>
#include "factapp.h"

int main(int argc, char *argv[]) {
   cl_object factSymbol;
   cl_object result;
   cl_fixnum value;

   printf("Attempting to initialize lisp.\n");

   printf("Attempting to call the embedded lisp factorial function with a 
value of 2.\n");

   factSymbol = c_string_to_object("FIB");
   printf("... have the function symbol\n");

   result = funcall(2, factSymbol, MAKE_FIXNUM(2));
   printf("... have made the funcall\n");

   value = fixint(result);
   printf("... have the value!\n");

   printf("Result of fact is %d\n", value);

More information about the ecl-devel mailing list