Embeddable Common Lisp (ECL): load shared library with extension functions

635 Views Asked by At

Is it possible to load a shared library in ECL, import some C functions which receive and return cl_object (as if they were defined with ecl_def_c_function()) and invoke them in REPL (without compiling a *.lisp file)?

For example:

// file 'extensions.c' compiled to 'extensions.so'

cl_object
    do_something
        (cl_object arg)
{
    cl_object
        result = ...;

    return result;
}

; in ECL REPL
(uffi:load-foreign-library #p".../extensions.so")
... ; importing stuff
(format t "got: ~a~%" (do-something "text"))

As I found there's no way of telling ECL (via UFFI) that C functions deal with cl_object, not a regular pointer (void*).

1

There are 1 best solutions below

0
AlexDarkVoid On BEST ANSWER

Looks like you can't do it as easy as in Python. The only solution I found so far:

extlib.c

#include <stdio.h>
#include <ecl/ecl.h>

static
cl_object
    make_pair
        (cl_object arg)
{
    return cl_cons(arg, arg);
}

void
    init_extlib
        (void)
{
    ecl_def_c_function(
        ecl_read_from_cstring("make-pair"),
        make_pair,
        1
    );
}

Compile it:

clang `ecl-config --cflags` extlib.c -shared -fPIC -o extlib.so `ecl-config --libs`

load-extlib.lisp

(uffi:load-foreign-library "~/extlib.so")
(uffi:def-function ("init_extlib" init-extlib)
                   ()
                   :returning :void)
(init-extlib)

Compile it:

ecl -compile load-extlib.lisp -o load-extlib.fas

Load & test it:

ecl -load load-extlib.fas
> (make-pair "blah")

("blah" . "blah")