FFI cannot find symbol in shared library despite nm utility saying otherwise

I'm trying to create a dynamic library out of sxiv since I need to have a programmatically controllable image viewer, I don't really have much experience with shared libraries so it might be an error outside of Racket, but nm libsxiv.so | grep ' T ' | grep quick shows that my lib_quickstart function is visible, yet I get an error

../../../../usr/share/racket/collects/ffi/unsafe.rkt:255:20: ffi-obj: could not find export from foreign library
  name: lib_quickstart
  library: /path/to/lib/sxiv/libsxiv.so
  system error: /path/to/lib/sxiv/libsxiv.so: undefined symbol: lib_quickstart

I'm dumbfounded by it.

This is the branch for the shared library.
It can be compiled with make -f Makefile.so

2 Likes

There could be several causes, but here is one possibility.

If you are using DrRacket to experiment with your own dynamic library,
then (if I recall correctly) you need to restart DrRacket when you update libsxiv.so.
When the shared library is loaded the first time it is loaded from the file system.
Subsequent times the already loaded library is used again.

So if you at some point loaded libsxiv and then later added lib_quickstart
then ffi-obj can't find the new symbol, since it is using the cached version.

I think, the problem comes from the way the OS handles dynamic libaries.
If so, you'll see similar results in Emacs using racket-mode.

The easiest way to deal with this (if this actually is the cause of the problem),
is run your test program from the terminal.

4 Likes

It appears that was the problem, thanks!

1 Like