[plt-scheme] ffi: dlopen in unix

From: Eli Barzilay (eli at barzilay.org)
Date: Tue Oct 10 23:09:45 EDT 2006

On Oct 10, Jon Rafkind wrote:
>     Im using FFI to test two different versions of the same library,
> basically to regression test a newer library with an older one. I
> attempted to achieve this by binding to the functions inside a unit,
> where the name of the library is passed in. Long story short since
> both libraries have the same exact symbols I was running into a
> problem where a function A that internally called function B would
> use function B from whichever library was loaded first. The solution
> is to not use the RTLD_GLOBAL flag to dlopen in foreign.c. I think
> RTLD_GLOBAL is only important if #f is passed into (ffi-lib) so that
> functions can be found in the already loaded program, but
> RTLD_GLOBAL should not be the default unless #f is given. Im not
> sure what other side-affects this might have on other people. Is
> this change reasonable to be part of mzscheme/foreign?

RTLD_GLOBAL is not used when you pass in #f -- this passes NULL to
dlopen, and no linking of new names is done.  OTOH, there are cases
where RTLD_GLOBAL is needed, when one library requires loading another
library in and wants to use its `bindings' (at least this is my
understanding of these things).  Maybe an optional argument should be
added to ffi-lib at some point?

> The problem more detailed is:
> x.c / libx.so
> void bar(){}
> void foo(){ bar(); }
> y.c / liby.so
> void bar(){}
> void foo(){ bar(); }
> (define xlib (ffi-lib "libx"))
> (define ylib (ffi-lib "liby"))
> (define x-foo (get-ffi-obj "foo" xlib (_fun -> _void))
> (define y-foo (get-ffi-obj "foo" ylib (_fun -> _void))
> (x-foo) ;; will call libx.so's foo() and bar()
> (y-foo) ;; will call liby.so's foo() and then libx.so's bar() because
> libx.so was loaded first

          ((lambda (x) (x x)) (lambda (x) (x x)))          Eli Barzilay:
                  http://www.barzilay.org/                 Maze is Life!

Posted on the users mailing list.