[plt-scheme] ffi: dlopen in unix
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!