[Ecls-list] Handling C/C++ pointers in lisp code (Was "can't compile with g++")

Juan Jose Garcia-Ripoll worm at arrakis.es
Mon Mar 1 01:15:12 UTC 2004


On Monday 01 March 2004 03:57, Larry Clapp wrote:
> I'm trying to interface with a C++ library.

Not easy.

> I've set C:*CC* to "g++", and also diddled a bit with C::*CC-FLAGS*.
> The compile line looks like

Have you compiled your ECL with the flag --enable-cxx??? If so, then
ECL will already be built with a C++ compiler and you do not need to
tweak any variables. This should solve some problems with prototypes, too.

> I have some sample code
> that looks like
>
>     (clines "#include \"cxx-ffi-test.h\"")
>
>     (defvar *a*
> 	(c-inline () () :int
> 	    "(int) new foo()"
>
> 	    :one-liner t))
>
>     (defun make-foo ()
>       (c-inline () () :int
> 	    "(int) new foo()"
>
> 	    :one-liner t))
>
>     (defun |foo::bar| (a-foo)
>       (c-inline (a-foo) (:int) :int
> 	    "((foo *) #0)->bar()"
>
> 	    :one-liner t))
>
>     ; which all works fine, until ...
>
>     (defclass baz ()
>       ((slot)))

But you know that lisp and C++ classes are not compatible *puzzled*
What is then the "baz" thing for?

The ECL implementation of UFFI is ongoing work, but in the meantime I
would suggest you to do something like...

    (clines "#include \"cxx-ffi-test.h\"")

    ;; Notice that we say a size of 0 because we do not want the
    ;; garbage collector to take care of the data in the foreign
    ;; structure.
    (defun make-foo ()
       (c-inline () () :object
	   "ecl_make_foreign(Cnil, 0, new foo())"
	   :one-liner t))

    (defun |foo::bar| (a-foo)
      (c-inline (a-foo) (:object) :int
            "((foo *)ecl_foreign_data_safe(#0, Cnil))->bar()"
            :one-liner t))

where "ecl_foreign_data_safe()" is a new function that has been introduced
in CVS today ;-) If you do not want to wait for it, an unsafe alternative...

    (defun |foo::bar| (a-foo)
      (c-inline (a-foo) (:object) :int
            "((foo*)((#0)->foreign.data))->bar()"
            :one-liner t))

And if you want better "typechecking", use a meaningful name for your type.
For instance a symbol, instead of "Cnil" up there.

Not that I checked it myself.

Ouch, before I forget it, to get the FFI objects you have to compile with
--with-ffi.

> The .h file for the generated code has
>     extern cl_object clos_ensure_class();
>

ECL tries to save a few bits by calling lisp compiled functions directly,
instead of via the lisp object that represents the function itself.
clos_ensure_class() is just a C declaration for the associated function
CLOS:ENSURE-CLASS. The problem is that a C compiler will not understand
typically the clos_ensure_class(...) prototype, while it is happy with
the old form. When working with a C++ compiler (i.e. if you used the
--with-cxx flag), the extern "C" {...} statements informs the compiler
about this old style declaration.

Juanjo





More information about the ecl-devel mailing list