[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