blob: 8d1e09e718863a2f87ecf17ce011a1511ac8370f [file] [log] [blame]
lh9ed821d2023-04-07 01:36:19 -07001.\" -*- nroff -*-
2.\" Copyright 1995 Yggdrasil Computing, Incorporated.
3.\" written by Adam J. Richter (adam@yggdrasil.com),
4.\" with typesetting help from Daniel Quinlan (quinlan@yggdrasil.com).
5.\"
6.\" This is free documentation; you can redistribute it and/or
7.\" modify it under the terms of the GNU General Public License as
8.\" published by the Free Software Foundation; either version 2 of
9.\" the License, or (at your option) any later version.
10.\"
11.\" The GNU General Public License's references to "object code"
12.\" and "executables" are to be interpreted as the output of any
13.\" document formatting or typesetting system, including
14.\" intermediate and printed output.
15.\"
16.\" This manual is distributed in the hope that it will be useful,
17.\" but WITHOUT ANY WARRANTY; without even the implied warranty of
18.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19.\" GNU General Public License for more details.
20.\"
21.\" You should have received a copy of the GNU General Public
22.\" License along with this manual; if not, write to the Free
23.\" Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139,
24.\" USA.
25.\"
26.TH DLOPEN 3 "16 May 1995" "Linux" "Linux Programmer's Manual"
27.SH NAME
28dlclose, dlerror, dlopen, dlsym \- Programming interface to dynamic linking loader.
29.SH SYNOPSIS
30.B #include <dlfcn.h>
31.sp
32.BI "void *dlopen (const char *" "filename" ", int " flag ");
33.br
34.BI "const char *dlerror(void);"
35.br
36.BI "void *dlsym(void *"handle ", char *"symbol ");"
37.br
38.BI "int dladdr(void *"address ", Dl_info *"dlip ");"
39.br
40.BI "int dlclose (void *"handle ");
41.sp
42Special symbols:
43.BR "_init" ", " "_fini" ". "
44.SH DESCRIPTION
45.B dlopen
46loads a dynamic library from the file named by the null terminated
47string
48.I filename
49and returns an opaque "handle" for the dynamic library.
50If
51.I filename
52is not an absolute path (i.e., it does not begin with a "/"), then the
53file is searched for in the following locations:
54.RS
55.PP
56A colon-separated list of directories in the user's
57\fBLD_LIBRARY\fP path environment variable.
58.PP
59The list of libraries specified in \fI/etc/ld.so.cache\fP.
60.PP
61\fI/usr/lib\fP, followed by \fI/lib\fP.
62.RE
63.PP
64If
65.I filename
66is a NULL pointer, then the returned handle is for the main program.
67.PP
68External references in the library are resolved using the libraries
69in that library's dependency list and any other libraries previously
70opened with the
71.B RTLD_GLOBAL
72flag.
73If the executable was linked
74with the flag "-rdynamic", then the global symbols in the executable
75will also be used to resolve references in a dynamically loaded
76library.
77.PP
78.I flag
79must be either
80.BR RTLD_LAZY ,
81meaning resolve undefined symbols as code from the dynamic library is
82executed, or
83.BR RTLD_NOW ,
84meaning resolve all undefined symbols before
85.B dlopen
86returns, and fail if this cannot be done.
87Optionally,
88.B RTLD_GLOBAL
89may be or'ed with
90.IR flag,
91in which case the external symbols defined in the library will be
92made available to subsequently loaded libraries.
93.PP
94If the library exports a routine named
95.BR _init ,
96then that code is executed before dlopen returns.
97If the same library is loaded twice with
98.BR dlopen() ,
99the same file handle is returned. The dl library maintains link
100counts for dynamic file handles, so a dynamic library is not
101deallocated until
102.B dlclose
103has been called on it as many times as
104.B dlopen
105has succeeded on it.
106.PP
107If
108.B dlopen
109fails for any reason, it returns NULL.
110A human readable string describing the most recent error that occurred
111from any of the dl routines (dlopen, dlsym or dlclose) can be
112extracted with
113.BR dlerror() .
114.B dlerror
115returns NULL if no errors have occurred since initialization or since
116it was last called. (Calling
117.B dlerror()
118twice consecutively, will always result in the second call returning
119NULL.)
120
121.B dlsym
122takes a "handle" of a dynamic library returned by dlopen and the null
123terminated symbol name, returning the address where that symbol is
124loaded. If the symbol is not found,
125.B dlsym
126returns NULL; however, the correct way to test for an error from
127.B dlsym
128is to save the result of
129.B dlerror
130into a variable, and then check if saved value is not NULL.
131This is because the value of the symbol could actually be NULL.
132It is also necessary to save the results of
133.B dlerror
134into a variable because if
135.B dlerror
136is called again, it will return NULL.
137.PP
138.B dladdr
139returns information about the shared library containing the memory
140location specified by
141.IR address .
142.B dladdr
143returns zero on success and non-zero on error.
144.PP
145.B dlclose
146decrements the reference count on the dynamic library handle
147.IR handle .
148If the reference count drops to zero and no other loaded libraries use
149symbols in it, then the dynamic library is unloaded. If the dynamic
150library exports a routine named
151.BR _fini ,
152then that routine is called just before the library is unloaded.
153.SH EXAMPLES
154.B Load the math library, and print the cosine of 2.0:
155.RS
156.nf
157.if t .ft CW
158#include <dlfcn.h>
159
160int main(int argc, char **argv) {
161 void *handle = dlopen ("/lib/libm.so", RTLD_LAZY);
162 double (*cosine)(double) = dlsym(handle, "cos");
163 printf ("%f\\n", (*cosine)(2.0));
164 dlclose(handle);
165}
166.if t .ft P
167.fi
168.PP
169If this program were in a file named "foo.c", you would build the program
170with the following command:
171.RS
172.LP
173gcc -rdynamic -o foo foo.c -ldl
174.RE
175.RE
176.LP
177.B Do the same thing, but check for errors at every step:
178.RS
179.nf
180.if t .ft CW
181#include <stdio.h>
182#include <dlfcn.h>
183
184int main(int argc, char **argv) {
185 void *handle;
186 double (*cosine)(double);
187 char *error;
188
189 handle = dlopen ("/lib/libm.so", RTLD_LAZY);
190 if (!handle) {
191 fputs (dlerror(), stderr);
192 exit(1);
193 }
194
195 cosine = dlsym(handle, "cos");
196 if ((error = dlerror()) != NULL) {
197 fputs(error, stderr);
198 exit(1);
199 }
200
201 printf ("%f\\n", (*cosine)(2.0));
202 dlclose(handle);
203}
204.if t .ft P
205.fi
206.RE
207.SH ACKNOWLEDGEMENTS
208The dlopen interface standard comes from Solaris.
209The Linux dlopen implementation was primarily written by
210Eric Youngdale with help from Mitch D'Souza, David Engel,
211Hongjiu Lu, Andreas Schwab and others.
212The manual page was written by Adam Richter.
213.SH SEE ALSO
214.BR ld(1) ,
215.BR ld.so(8) ,
216.BR ldconfig(8) ,
217.BR ldd(1) ,
218.BR ld.so.info .