[gambit-list] Prototype Gambit-C Erlang FFI

James Long longster at gmail.com
Mon Jul 16 01:56:08 EDT 2007


Hey guys, I don't know if anyone would be interested in this, but I've
been playing around with the idea of using Scheme underneath Erlang.
I'm very new to both Erlang and Scheme, and I was hoping to be able to
seamlessly create Scheme nodes within Erlang.  Because of Erlang's own
implementation of lightweight processes, it turns out that it can't be
as seamless as I had hoped, but I created a Gambit Erlang FFI to see
what it would be like anyway.

download it here (it only compiles on OS X, but very small tweaks to
the makefile could fix that):
http://dimlylitblog.com/projects/erlang-ffi.tar.gz

To be able to take advantage of all of Erlang's distributing
mechanisms, we need to use a proxy Erlang process and communicate
through ports, as described here:

http://www.erlang.org/doc/tutorial/erl_interface.html#5

This is what my FFI is based on.  It's a very basic implementation,
but it allows to write a Scheme app like this:

(load "erlang")

(define (bar num)
  (+ num 2))

(define (foo num)
  (* num 2))

(define (start)
  (start-erl)
  (let loop ((term (erl-receive)))
    (if (not (eqv? term 'close))
        (begin
          (let* ((fun (car term))
                 (args (cdr term))
                 (res (apply (eval fun) args)))
            (erl-send (erl-element res))
            (loop (erl-receive)))))))

(start)

And then in Erlang do this:

2> test:start("./test_process").
 <0.38.0>
 3> test:call({foo,10}).
 20
 4> test:call({foo,12}).
 24
 5> test:call({foo,25.2}).
 50.4000
 6> test:call({foo,12.25}).
 24.5000
 7> test:call({bar,100}).
 102
 8> test:call({bar,100.123}).
 102.123
 9>

Unfortunately, it's still not quite as solid as I would like.  It
communicates over standard in and out, which just seems hacky to me.
However, this is my first FFI and it was a good experience.  I have a
couple questions after writing this though:

1. One of the biggest problems which made development difficult is
that if the Scheme node hit any run-time error I cannot see it from
Erlang at all.  I could catch the exceptions myself and propagate them
properly, however there seems to be run-time errors which are
syntactual/macro errors, etc.  would there be any good methods to
detect and this log those kinds of errors?

2. When I compile the Erlang FFI, gcc gives this warning:
erlang.c:2530: warning: target of assignment not really an lvalue;
this will be a hard error in the future

and I think it's talking about assigning the result of a c function to
___result, such as

___result = ERL_TUPLE_SIZE(___CAST(ETERM*,___arg1));

any thoughts on that?

3. On OS X, when compiling the FFI into a loadable library, I give gsc
options to pass to the linker to link in the erl_interface libraries.
It compiles, but when run it gives the error that any of the Erlang c
functions can't be found in the flat namespace.  I thought that it
might be compiling the library with the two level namespace, so I
added -flat_namespace to the linker options but it didn't help.  I
finally figured out that it needed the option "bundle_loader" to work,
and I initially tried -bundle_loader $(gsi), but I have no idea why
that made it work.  I then tried -bundle_loader /bin/ls and even that
worked!  I understand the purpose of the bundle_loader option, but
this should all be in the flat namespace.  Has anyone encountered
this?

I think those are the only things I didn't really understand :)

James



More information about the Gambit-list mailing list