[Ecls-list] embedding questions

Peter Keller psilord at cs.wisc.edu
Sat Dec 8 18:27:27 UTC 2012


Hello,

Thank you for anwering my questions! I appreciate the time you spent
writing the answer.

On Sat, Dec 08, 2012 at 11:13:04AM +0100, Juan Jose Garcia-Ripoll wrote:
> On Sat, Dec 8, 2012 at 8:46 AM, Peter Keller <psilord at cs.wisc.edu> wrote:
> > 2. Are there any issues or special considerations with creating CLOS
> > objects and then calling methods on them from the C side? Will those
> > methods dispatch correctly on the arguments without additional poking
> > from the C side?
> >
> 
> I do not understand your concerns here. Function calls using a symbol name
> work the same in the interpreted and compiled world, and in the compiled
> world we use the same code that you will use in C.

Awesome. 

> > 3. I have a situation where I have C structures full of data and want
> > to push them into/bring them out of the Lisp side. Are things like
> > si_make_structure what I'm supposed to use on the C side? Are there
> > idioms I should know about to perform this type of data translation?
> >
> 
> NO! Please learn to use foreign function interfaces, either the ones
> supplied by ECL, http://ecls.sourceforge.net/new-manual/ or some other one,
> such as CFFI.
> 
> Note that it is definitely easier to write C code embedded in lisp code
> than try to reproduce all functionality of lisp in your plugin, which is
> why you should consider using ECL to compile your code.

I know the CFFI can be used to define callbacks from C into lisp, as in
this url:
http://common-lisp.net/project/cffi/manual/cffi-manual.html#Callbacks
but it is (in my understanding, which could be wrong) generally for
writing a lisp wrapper around a C library. I would like to do the
converse operation.

Here is a (small) example of what I'd like to do:

Suppose the plugin interface looks like this:

-------------------------
struct thing
{
    int a;
    double g;
}

int foo(struct thing var, char *str);
-------------------------

So, in the C world, I'd create some code which fills in foo(),
construct a shared library, then tell the application where it is.
The application only ever calls the C functions passing stuff to it
from a collection of data structures held in the application.

My initial understanding is that I would write a C function like (I'm
just learning how to do this, so this is likely wrong in some details):

int foo(struct thing *var, char *str)
{
    /* convert the struct */
    C_object lisp_fixnum = ecl_fixnum(var->a);
    C_object lisp_double = ecl_make_double_float(var->g);
    C_object type = c_string_to_object("THING");
    C_object lisp_var = si_make_strucure(3, type, lisp_fixnum, lisp_double);

    /* convert the string */
    C_object lisp_str = c_string_to_object(str);

    /* call the function */
    C_object lisp_result = 
        cl_funcall(2,c_string_to_object("FOO"),lisp_var,lisp_str);

    /* convert result back into C */
    return fix(lisp_result);
}

And then there would be a lisp file like:

(defstruct thing a g)

;; and then the plugin author would write this function instead to implement
;; the functionality of C's foo.
(defun foo (thing str)
   (format t "thing: ~A ~A~%" (thing-a thing) (thing-g thing))
   (format t "string is: ~A~%" str)
   0)

Is what I'm doing really off base?

> Really, there is nothing different in embedding ECL from running normal
> lisp code. Please use this for reasoning about how things work: your
> standard ECL interpreter is just a stupid embedding of ECL in a four lines
> program!

I figure this is the case, I just have to learn the initial incantations
before I'm off on my own.

I'm willing to write some tutorials or edit the manual and add this
kind knowledge wherever you'd like.

Thank you very much!

-pete




More information about the ecl-devel mailing list