[Ecls-list] Embedding ECL - how?
Dr. Edmund Weitz
edi at agharta.de
Tue Jan 22 00:21:01 UTC 2002
First of all thanks for your fast and informative reply. And good luck
with your IKEA furniture - I know how hard this can be sometimes... :)
Let me also add that I would want to volunteer for writing a tutorial
or extend the developer documentation once I've completely understood
the stuff myself. But first of all, I still have a couple of
questions. Here's what I did:
I wrote a small C snippet and called it 'lib.c':
#include <stdio.h>
void print_something () {
printf("This is a test.\n");
}
Then I built my little library...
gcc -c -o lib lib.c
ar -q libmylib.a lib
...and an image according to your guidelines:
(c::build-program "myimage" :ld-flags '("-L. -lmylib") :prologue-code "print_something();")
Calling 'myimage' did exactly what I expected: The line 'This is a
test.' was printed and then I was thrown into the REPL.
Afterward I did...
(c::build-program "myimage" :ld-flags '("-L. -lmylib") :epilogue-code "print_something();")
...and also got what I expected: Only the above-mentioned line was
printed, no REPL. Fine.
Now, what I actually wanted to have was a way to call into ECL
non-interactively, i.e. without a REPL. So I tried something like this:
#include "/usr/local/lib/ecl/h/ecl.h"
void call_into_lisp () {
clLprint(1, MAKE_FIXNUM(3));
}
then
gcc -c -o lib lib.c
rm libmylib.a
ar -q libmylib.a lib
and
(c::build-program "myimage" :ld-flags '("-L. -lmylib") :prologue-code "call_into_lisp();")
which resulted in a segmentation fault when calling 'myimage'. No
surprise here, 'cause obviously ECL didn't have a chance to set up its
environment yet.
So, I changed the call to
(c::build-program "myimage" :ld-flags '("-L. -lmylib") :epilogue-code "call_into_lisp();")
everything worked fine - the number 3 was printed, and the program
exited.
So far, so good. Now, how do I call my own functions? If I
COMPILE-FILE a file with my own Lisp definitions, these functions
obviously are not compiled into functions whose resemble the
conventions described in the developer documentation. Instead of, say,
'clLfac' I get something like 'L1' or 'L2'. So, I though I should try
EVAL to call these function (although I'd rather call them directly of
course.)
I followed one of the examples from the developer documentation and
wrote this little C function:
#include "/usr/local/lib/ecl/h/ecl.h"
void call_into_lisp () {
cl_object form;
cl_object buffer;
form = c_string_to_object("(print 3)");
buffer = OBJNULL;
eval(form, &buffer, Cnil);
eval(form, &buffer, Cnil);
}
and, after building my library, did:
(c::build-program "myimage" :ld-flags '("-L. -lmylib") :epilogue-code "call_into_lisp();")
This resulted in
edi at bird:~> ./myimage
Segmentation violation.
Wrong type argument to a compiled function.
Top level.
>
Hmm... What's wrong with that? Will EVAL only work inside of the REPL?
I decided to give it another try and call 'clLeval' directly, like so:
#include "/usr/local/lib/ecl/h/ecl.h"
void eval_string (char *string) {
cl_object form;
form = c_string_to_object(string);
clLeval(0, form);
}
and
(c::build-program "myimage" :ld-flags '("-L. -lmylib") :epilogue-code "eval_string(\"(print 3)\");")
This time I got:
edi at bird:~> ./myimage
Function SI:TOP-LEVEL requires one argument,
but only zero were supplied.
Top level.
>
So this is basically where I'm stuck now. I actually want to write a
couple of Lisp functions, COMPILE-FILE them and want to be able to
call them non-interactively from a C program, but I guess I'm not
there yet. Is this possible at all with ECL?
Thanks in advance for your help,
Edi.
More information about the ecl-devel
mailing list