Load Shared Library by Path at Runtime

Can't load dynamic shared library at runtime including another shared library in C++

There is nothing wrong with this design. But when you dlopen() a shared library, all it's symbols need to be resolved. Your error means that you do not have the path to .so your library depends on in LD_LIBRARY_PATH. To check what library it needs, use

ldd <your library.so>

Than add the directory where this library resides to LD_LIBRARY_PATH.

Run-time linking to dynamic libraries not on LD_LIBRARY_PATH

You can either

  1. Write a wrapper script to always include LD_LIBRARY_PATH before calling the actual program (more flexible).
  2. Add -Wl,-rpath=<directory> to your linker options to add a directory to the runtime library search path. So assuming you have a libfoo.so and your program and DSO are located in the same directory, your compilation command could look like this: gcc -o myprogam main.c -L. -lfoo -Wl,-rpath='$ORIGIN'.

Update: As correctly noted by Maxim, setting -rpath=. is dangerous and should be avoided.

For -Wl,, see the gcc manpage and for -rpath see the ld manpage.

library path when dynamically loaded?

The dynamic linker actually searches several places to find each dynamic library. These include (from man ld.so):

  • Paths given by the environment variable LD_LIBRARY_PATH
  • Paths baked into the binary load the library under the DT_RUNPATH entry
  • The cache file /etc/ld.so.cache
  • /lib and /usr/lib

If you want to get the path for a specific shared library, I would recommend the dladdr function. From the man page:

The function dladdr() takes a function pointer and tries to resolve
name and file where it is located. Information is stored in the
Dl_info structure:

typedef struct {
const char *dli_fname; /* Pathname of shared object that
contains address */
void *dli_fbase; /* Address at which shared object
is loaded */
const char *dli_sname; /* Name of nearest symbol with address
lower than addr */
void *dli_saddr; /* Exact address of symbol named
in dli_sname */
} Dl_info;

If no symbol matching addr could be found, then dli_sname and
dli_saddr are set to NULL.

dladdr() returns 0 on error, and non-zero on success.

So you just give it a function pointer, and it will give you the name of the file which supplies it and a bunch of other information. So for instance, you could have a constructor in a library call this on itself to find out the full path of the library:

#define _GNU_SOURCE
#include <dlfcn.h>
#include <stdio.h>

__attribute__((constructor))
void on_load(void) {
Dl_info dl_info;
dladdr((void *)on_load, &dl_info);
fprintf(stderr, "module %s loaded\n", dl_info.dli_fname);
}

This function also works on OS X with the same semantics.



Related Topics



Leave a reply



Submit