[Ecls-list] Embedding ECL in a C++ app.

Juan Jose Garcia Ripoll lisp at arrakis.es
Mon Feb 6 02:51:04 UTC 2006


On Thu, 2006-02-02 at 14:53 +0200, Ivan Toshkov wrote:
> At last, a few days ago a colleague of mine actually found the
> problem:  ECL and our system both had the same file named "config.h". 
> They both were in the include path, but ours was first, so ECL found
> it and, naturally, failed to compile.
> So, my first suggestion is to move most of the include files in a
> subdirectory, named e.g. "ecl" and include them like this:
> 
> #include <ecl/config.h>

I take note.

> BTW, I found that at cl_defvar and cl_defparameter are declared in the
> external.h but are never defined.  Should be easy to remove them, but
> probably better to implement?

They do no longer exist. cl_* refer only to lisp functions and not to
special forms so as to keep things consistent. You can, however, define
a simple macro

#define ecl_defparameter(s,v) \
    do { si_Xmake_special(s); ECL_SETQ(s,v); } while (0);

I might include it in the next release. Seems harmless.

> 1.  How to catch errors in the C++ part?  I use si_safe_eval to run
> the Lisp code.  When there is an error in it, the Lisp debugger runs. 
> In a while, I'd probably try to have a REPL, listening on a different
> port, but for now (and for the production system), I'd like to just
> log the error.

This should not happen. At least the latest revision aims to guarantee
that the debugger will not be invoked. As for capturing conditions,
there is an example using HANDLER-CASE in a previous mail to the list.

> 2.  The C++ app doesn't use a garbage collector, but I don't know what
> happens when I link it with ECL, and through that, with Boehm's GC. 
> Any pointers (pun unintended, but noticed)?

ECL instructs the GC to only keep data that is pointed to by either
	- lisp variables
	- the lisp stack
	- the VALUES vector
	- some automatic variable in the C stack
If you want to prevent some lisp objects from being garbage collected,
use one of these methods, or store them in a C global variable which
should be registered as a root to be scanned by the garbage collector.
This is done with 
	ecl_register_static_root(&the_variable)

> 3.  I don't want to complicate the build process more than it's
> absolutely necessary, so I don't use the fancy Lisp like C++ macros
> @(defun ...) and friends, but I still want to define Lisp functions
> with &optional, &keyword, and &rest argument lists from C.  How?

As Michael pointed out before, you can use ECL's preprocessor to
generate the C/C++ source files. Otherwise you will have to follow a
number of steps which are rather complicated, in order to retrieve the
optional and keyword arguments. I show below you the preprocessed code
for 

@(defun string= (string1 string2 &key (start1 MAKE_FIXNUM(0)) end1
		   (start2 MAKE_FIXNUM(0)) end2)

As you will see, it involves using C's arglists and a dedicated function
to parse it. If you positively want to avoid using 'dpp', I'd rather
code such functions in lisp and use the FFI and C-inline instead.

Regards,

Juanjo

----

cl_object cl_stringE(cl_narg narg, cl_object string1, cl_object
string2, ...)
{
	cl_index s1, e1, s2, e2;
	static cl_object KEYS[4] = {(cl_object)(cl_symbols+1303),
(cl_object)(cl_symbols+1222), (cl_object)(cl_symbols+1304),
(cl_object)(cl_symbols+1223)};
	cl_object start1;
	cl_object end1;
	cl_object start2;
	cl_object end2;
	cl_object KEY_VARS[8];
	cl_va_list ARGS;
	cl_va_start(ARGS, string2, narg, 2);
	if (narg < 2) FEwrong_num_arguments((cl_object)(cl_symbols+820));
	cl_parse_key(ARGS, 4, KEYS, KEY_VARS, NULL, 0);
	if (KEY_VARS[4]==Cnil) {
	  start1 = MAKE_FIXNUM(0);
	} else {
	  start1 = KEY_VARS[0];
	}
	if (KEY_VARS[5]==Cnil) {
	  end1 = Cnil;
	} else {
	  end1 = KEY_VARS[1];
	}
	if (KEY_VARS[6]==Cnil) {
	  start2 = MAKE_FIXNUM(0);
	} else {
	  start2 = KEY_VARS[2];
	}
	if (KEY_VARS[7]==Cnil) {
	  end2 = Cnil;
	} else {
	  end2 = KEY_VARS[3];
	}






More information about the ecl-devel mailing list