123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218 |
- .\" -*- nroff -*-
- .\" Copyright 1995 Yggdrasil Computing, Incorporated.
- .\" written by Adam J. Richter (adam@yggdrasil.com),
- .\" with typesetting help from Daniel Quinlan (quinlan@yggdrasil.com).
- .\"
- .\" This is free documentation; you can redistribute it and/or
- .\" modify it under the terms of the GNU General Public License as
- .\" published by the Free Software Foundation; either version 2 of
- .\" the License, or (at your option) any later version.
- .\"
- .\" The GNU General Public License's references to "object code"
- .\" and "executables" are to be interpreted as the output of any
- .\" document formatting or typesetting system, including
- .\" intermediate and printed output.
- .\"
- .\" This manual is distributed in the hope that it will be useful,
- .\" but WITHOUT ANY WARRANTY; without even the implied warranty of
- .\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- .\" GNU General Public License for more details.
- .\"
- .\" You should have received a copy of the GNU General Public
- .\" License along with this manual; if not, write to the Free
- .\" Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139,
- .\" USA.
- .\"
- .TH DLOPEN 3 "16 May 1995" "Linux" "Linux Programmer's Manual"
- .SH NAME
- dlclose, dlerror, dlopen, dlsym \- Programming interface to dynamic linking loader.
- .SH SYNOPSIS
- .B #include <dlfcn.h>
- .sp
- .BI "void *dlopen (const char *" "filename" ", int " flag ");
- .br
- .BI "const char *dlerror(void);"
- .br
- .BI "void *dlsym(void *"handle ", char *"symbol ");"
- .br
- .BI "int dladdr(void *"address ", Dl_info *"dlip ");"
- .br
- .BI "int dlclose (void *"handle ");
- .sp
- Special symbols:
- .BR "_init" ", " "_fini" ". "
- .SH DESCRIPTION
- .B dlopen
- loads a dynamic library from the file named by the null terminated
- string
- .I filename
- and returns an opaque "handle" for the dynamic library.
- If
- .I filename
- is not an absolute path (i.e., it does not begin with a "/"), then the
- file is searched for in the following locations:
- .RS
- .PP
- A colon-separated list of directories in the user's
- \fBLD_LIBRARY\fP path environment variable.
- .PP
- The list of libraries specified in \fI/etc/ld.so.cache\fP.
- .PP
- \fI/usr/lib\fP, followed by \fI/lib\fP.
- .RE
- .PP
- If
- .I filename
- is a NULL pointer, then the returned handle is for the main program.
- .PP
- External references in the library are resolved using the libraries
- in that library's dependency list and any other libraries previously
- opened with the
- .B RTLD_GLOBAL
- flag.
- If the executable was linked
- with the flag "-rdynamic", then the global symbols in the executable
- will also be used to resolve references in a dynamically loaded
- library.
- .PP
- .I flag
- must be either
- .BR RTLD_LAZY ,
- meaning resolve undefined symbols as code from the dynamic library is
- executed, or
- .BR RTLD_NOW ,
- meaning resolve all undefined symbols before
- .B dlopen
- returns, and fail if this cannot be done.
- Optionally,
- .B RTLD_GLOBAL
- may be or'ed with
- .IR flag,
- in which case the external symbols defined in the library will be
- made available to subsequently loaded libraries.
- .PP
- If the library exports a routine named
- .BR _init ,
- then that code is executed before dlopen returns.
- If the same library is loaded twice with
- .BR dlopen() ,
- the same file handle is returned. The dl library maintains link
- counts for dynamic file handles, so a dynamic library is not
- deallocated until
- .B dlclose
- has been called on it as many times as
- .B dlopen
- has succeeded on it.
- .PP
- If
- .B dlopen
- fails for any reason, it returns NULL.
- A human readable string describing the most recent error that occurred
- from any of the dl routines (dlopen, dlsym or dlclose) can be
- extracted with
- .BR dlerror() .
- .B dlerror
- returns NULL if no errors have occurred since initialization or since
- it was last called. (Calling
- .B dlerror()
- twice consecutively, will always result in the second call returning
- NULL.)
- .B dlsym
- takes a "handle" of a dynamic library returned by dlopen and the null
- terminated symbol name, returning the address where that symbol is
- loaded. If the symbol is not found,
- .B dlsym
- returns NULL; however, the correct way to test for an error from
- .B dlsym
- is to save the result of
- .B dlerror
- into a variable, and then check if saved value is not NULL.
- This is because the value of the symbol could actually be NULL.
- It is also necessary to save the results of
- .B dlerror
- into a variable because if
- .B dlerror
- is called again, it will return NULL.
- .PP
- .B dladdr
- returns information about the shared library containing the memory
- location specified by
- .IR address .
- .B dladdr
- returns zero on success and non-zero on error.
- .PP
- .B dlclose
- decrements the reference count on the dynamic library handle
- .IR handle .
- If the reference count drops to zero and no other loaded libraries use
- symbols in it, then the dynamic library is unloaded. If the dynamic
- library exports a routine named
- .BR _fini ,
- then that routine is called just before the library is unloaded.
- .SH EXAMPLES
- .B Load the math library, and print the cosine of 2.0:
- .RS
- .nf
- .if t .ft CW
- #include <dlfcn.h>
- int main(int argc, char **argv) {
- void *handle = dlopen ("/lib/libm.so", RTLD_LAZY);
- double (*cosine)(double) = dlsym(handle, "cos");
- printf ("%f\\n", (*cosine)(2.0));
- dlclose(handle);
- }
- .if t .ft P
- .fi
- .PP
- If this program were in a file named "foo.c", you would build the program
- with the following command:
- .RS
- .LP
- gcc -rdynamic -o foo foo.c -ldl
- .RE
- .RE
- .LP
- .B Do the same thing, but check for errors at every step:
- .RS
- .nf
- .if t .ft CW
- #include <stdio.h>
- #include <dlfcn.h>
- int main(int argc, char **argv) {
- void *handle;
- double (*cosine)(double);
- char *error;
- handle = dlopen ("/lib/libm.so", RTLD_LAZY);
- if (!handle) {
- fputs (dlerror(), stderr);
- exit(1);
- }
- cosine = dlsym(handle, "cos");
- if ((error = dlerror()) != NULL) {
- fputs(error, stderr);
- exit(1);
- }
- printf ("%f\\n", (*cosine)(2.0));
- dlclose(handle);
- }
- .if t .ft P
- .fi
- .RE
- .SH ACKNOWLEDGEMENTS
- The dlopen interface standard comes from Solaris.
- The Linux dlopen implementation was primarily written by
- Eric Youngdale with help from Mitch D'Souza, David Engel,
- Hongjiu Lu, Andreas Schwab and others.
- The manual page was written by Adam Richter.
- .SH SEE ALSO
- .BR ld(1) ,
- .BR ld.so(8) ,
- .BR ldconfig(8) ,
- .BR ldd(1) ,
- .BR ld.so.info .
|