[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