DLOPEN(3)                 Linux Programmer’s Manual                 DLOPEN(3)

NAME
       dladdr,  dlclose,  dlerror, dlopen, dlsym, dlvsym - programming inter-
       face to dynamic linking loader

SYNOPSIS
       #include <dlfcn.h>

       void *dlopen(const char *filename, int flag);

       char *dlerror(void);

       void *dlsym(void *handle, const char *symbol);

       int dlclose(void *handle);

DESCRIPTION
       The four functions dlopen(), dlsym(), dlclose(),  dlerror()  implement
       the interface to the dynamic linking loader.

   dlerror
       The  function dlerror() returns a human readable string describing the
       most recent error that occurred from any of the dl  routines  (dlopen,
       dlsym  or  dlclose) since the last call to dlerror().  It returns NULL
       if no errors have occurred since initialization or since it  was  last
       called.

   dlopen
       The  function  dlopen()  loads  the  dynamic library file named by the
       null-terminated string filename and returns an opaque "handle" for the
       dynamic library.  If filename is NULL, then the returned handle is for
       the main program.  If filename contains a  slash  ("/"),  then  it  is
       interpreted  as  a  (relative  or  absolute) pathname.  Otherwise, the
       dynamic linker searches for the library as follows (see  ld.so(8)  for
       further details):

       o      (ELF  only) If the executable file for the calling program con-
              tains a DT_RPATH tag, and does not contain  a  DT_RUNPATH  tag,
              then the directories listed in the DT_RPATH tag are searched.

       o      If  the environment variable LD_LIBRARY_PATH is defined to con-
              tain a colon-separated list  of  directories,  then  these  are
              searched.   (As a security measure this variable is ignored for
              set-UID and set-GID programs.)

       o      (ELF only) If the executable file for the calling program  con-
              tains a DT_RUNPATH tag, then the directories listed in that tag
              are searched.

       o      The cache file /etc/ld.so.cache (maintained by ldconfig(8))  is
              checked to see whether it contains an entry for filename.

       o      The directories /lib and /usr/lib are searched (in that order).

       If the library has dependencies on other shared libraries, then  these
       are  also  automatically  loaded  by the dynamic linker using the same
       rules.  (This process may occur recursively,  if  those  libraries  in
       turn have dependencies, and so on.)

       The  value of flag can be either RTLD_LAZY or RTLD_NOW.  When RTLD_NOW
       is specified, or the environment variable LD_BIND_NOW is set to a non-
       empty string, all undefined symbols in the library are resolved before
       dlopen() returns. If this  cannot  be  done,  an  error  is  returned.
       Otherwise  binding  is  lazy:  symbol  values  are first resolved when
       needed.

       Optionally, RTLD_GLOBAL may be or’ed into  flag,  in  which  case  the
       external  symbols  defined  in  the library will be made available for
       symbol resolution of subsequently loaded libraries.  (The converse  of
       RTLD_GLOBAL is RTLD_LOCAL.  This is the default.)

       If  filename  is  a  NULL pointer, then the returned handle is for the
       main program.  When given to dlsym(), this handle causes a search  for
       a  symbol in the main program, followed by all shared libraries loaded
       at program startup, and then all shared libraries loaded  by  dlopen()
       with the flag RTLD_GLOBAL.

       External references in the library are resolved using the libraries in
       that library’s dependency list  and  any  other  libraries  previously
       opened  with  the RTLD_GLOBAL flag.  If the executable was linked with
       the flag "-rdynamic" (or, synonymously, "--export-dynamic"), then  the
       global  symbols  in the executable will also be used to resolve refer-
       ences in a dynamically loaded library.

       If the same library is loaded again with dlopen(), the same file  han-
       dle is returned. The dl library maintains reference counts for library
       handles, so a dynamic library is not deallocated until  dlclose()  has
       been  called  on it as many times as dlopen() has succeeded on it. The
       _init routine, if present, is only called once. But a subsequent  call
       with RTLD_NOW may force symbol resolution for a library earlier loaded
       with RTLD_LAZY.

       If dlopen() fails for any reason, it returns NULL.

   dlsym
       The function dlsym() takes a "handle" of a dynamic library returned by
       dlopen and the NUL-terminated symbol name, returning the address where
       that symbol is loaded into memory.  If the symbol is not found, in the
       specified  library  or  any  of  the libraries that were automatically
       loaded by dlopen() when that library was loaded, dlsym() returns NULL.
       (The  search  performed by dlsym() is breadth first through the depen-
       dency tree of these libraries.)  Since the value of the  symbol  could
       actually be NULL (so that a NULL return from dlsym() need not indicate
       an error), the correct way to test for an error is to  call  dlerror()
       to  clear  any  old error conditions, then call dlsym(), and then call
       dlerror() again, saving its return value into a  variable,  and  check
       whether this saved value is not NULL.

       There are two special pseudo-handles, RTLD_DEFAULT and RTLD_NEXT.  The
       former will find the first occurrence of the desired symbol using  the
       default library search order. The latter will find the next occurrence
       of a function in the search order after  the  current  library.   This
       allows  one  to  provide a wrapper around a function in another shared
       library.

   dlclose
       The function dlclose() decrements the reference count on  the  dynamic
       library  handle  handle.   If the reference count drops to zero and no
       other loaded libraries use symbols in it, then the dynamic library  is
       unloaded.

       The function dlclose() returns 0 on success, and non-zero on error.

   The obsolete symbols _init and _fini
       The  linker  recognizes special symbols _init and _fini.  If a dynamic
       library exports a routine named _init,  then  that  code  is  executed
       after  the  loading,  before  dlopen() returns. If the dynamic library
       exports a routine named _fini, then that routine is called just before
       the library is unloaded.  In case you  need to  avoid  linking against
       the system startup files, this can be done by giving  gcc  the  "-nos-
       tartfiles" parameter on the command line.

       Using these routines, or the gcc -nostartupfiles or -nostdlib options,
       is not recommended. Their use may result in undesired behavior,  since
       the  constructor/destructor routines will not be executed (unless spe-
       cial measures are taken).

       Instead,    libraries    should    export    routines    using     the
       __attribute__((constructor))  and __attribute__((destructor)) function
       attributes.  See the gcc info pages for information  on  these.   Con-
       structor  routines  are executed before dlopen returns, and destructor
       routines are executed before dlclose returns.

GNU EXTENSIONS
       Glibc adds two functions not described by POSIX, with prototypes

       #define GNU_SOURCE
       #include <dlfcn.h>

       int dladdr(void *addr, Dl_info *info);

       void *dlvsym(void *handle, char *symbol, char *version);

       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;/* File name of defining object */
         void *dli_fbase;      /* Load address of that object */
         const char *dli_sname;/* Name of nearest lower symbol */
         void *dli_saddr;      /* Exact value of nearest symbol */
       } Dl_info;

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

       The function dlvsym() does the same as dlsym()  but  takes  a  version
       string as additional argument.

EXAMPLE
       Load the math library, and print the cosine of 2.0:
              #include <stdio.h>
              #include <dlfcn.h>

              int main(int argc, char **argv) {
                  void *handle;
                  double (*cosine)(double);
                  char *error;

                  handle = dlopen ("libm.so", RTLD_LAZY);
                  if (!handle) {
                      fprintf (stderr, "%s\n", dlerror());
                      exit(1);
                  }

                  dlerror();    /* Clear any existing error */
                  *(void **) (&cosine) = dlsym(handle, "cos");
                  if ((error = dlerror()) != NULL)  {
                      fprintf (stderr, "%s\n", error);
                      exit(1);
                  }

                  printf ("%f\n", (*cosine)(2.0));
                  dlclose(handle);
                  return 0;
              }

       If this program were in a file named "foo.c", you would build the pro-
       gram with the following command:

              gcc -rdynamic -o foo foo.c -ldl

       Libraries exporting _init() and _fini() will want to  be  compiled  as
       follows, using bar.c as the example name:

              gcc -shared -nostartfiles -o bar bar.c

NOTES
       The  symbols  RTLD_DEFAULT and RTLD_NEXT are defined by <dlfcn.h> only
       when _GNU_SOURCE was defined before including it.

HISTORY
       The dlopen interface standard comes from SunOS. That system  also  has
       dladdr, but not dlvsym.

CONFORMING TO
       POSIX 1003.1-2003 describes dlclose, dlerror, dlopen, dlsym.

SEE ALSO
       ld(1),  ldd(1),  ld.so(8),  ldconfig(8),  ld.so  info  pages, gcc info
       pages, ld info pages

Linux                             2003-11-17                        DLOPEN(3)