1 |
1325 |
phoenix |
.\" -*- 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
|
28 |
|
|
dlclose, dlerror, dlopen, dlsym \- Programming interface to dynamic linking loader.
|
29 |
|
|
.SH SYNOPSIS
|
30 |
|
|
.B #include
|
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
|
42 |
|
|
Special symbols:
|
43 |
|
|
.BR "_init" ", " "_fini" ". "
|
44 |
|
|
.SH DESCRIPTION
|
45 |
|
|
.B dlopen
|
46 |
|
|
loads a dynamic library from the file named by the null terminated
|
47 |
|
|
string
|
48 |
|
|
.I filename
|
49 |
|
|
and returns an opaque "handle" for the dynamic library.
|
50 |
|
|
If
|
51 |
|
|
.I filename
|
52 |
|
|
is not an absolute path (i.e., it does not begin with a "/"), then the
|
53 |
|
|
file is searched for in the following locations:
|
54 |
|
|
.RS
|
55 |
|
|
.PP
|
56 |
|
|
A colon-separated list of directories in the user's
|
57 |
|
|
\fBLD_LIBRARY\fP path environment variable.
|
58 |
|
|
.PP
|
59 |
|
|
The 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
|
64 |
|
|
If
|
65 |
|
|
.I filename
|
66 |
|
|
is a NULL pointer, then the returned handle is for the main program.
|
67 |
|
|
.PP
|
68 |
|
|
External references in the library are resolved using the libraries
|
69 |
|
|
in that library's dependency list and any other libraries previously
|
70 |
|
|
opened with the
|
71 |
|
|
.B RTLD_GLOBAL
|
72 |
|
|
flag.
|
73 |
|
|
If the executable was linked
|
74 |
|
|
with the flag "-rdynamic", then the global symbols in the executable
|
75 |
|
|
will also be used to resolve references in a dynamically loaded
|
76 |
|
|
library.
|
77 |
|
|
.PP
|
78 |
|
|
.I flag
|
79 |
|
|
must be either
|
80 |
|
|
.BR RTLD_LAZY ,
|
81 |
|
|
meaning resolve undefined symbols as code from the dynamic library is
|
82 |
|
|
executed, or
|
83 |
|
|
.BR RTLD_NOW ,
|
84 |
|
|
meaning resolve all undefined symbols before
|
85 |
|
|
.B dlopen
|
86 |
|
|
returns, and fail if this cannot be done.
|
87 |
|
|
Optionally,
|
88 |
|
|
.B RTLD_GLOBAL
|
89 |
|
|
may be or'ed with
|
90 |
|
|
.IR flag,
|
91 |
|
|
in which case the external symbols defined in the library will be
|
92 |
|
|
made available to subsequently loaded libraries.
|
93 |
|
|
.PP
|
94 |
|
|
If the library exports a routine named
|
95 |
|
|
.BR _init ,
|
96 |
|
|
then that code is executed before dlopen returns.
|
97 |
|
|
If the same library is loaded twice with
|
98 |
|
|
.BR dlopen() ,
|
99 |
|
|
the same file handle is returned. The dl library maintains link
|
100 |
|
|
counts for dynamic file handles, so a dynamic library is not
|
101 |
|
|
deallocated until
|
102 |
|
|
.B dlclose
|
103 |
|
|
has been called on it as many times as
|
104 |
|
|
.B dlopen
|
105 |
|
|
has succeeded on it.
|
106 |
|
|
.PP
|
107 |
|
|
If
|
108 |
|
|
.B dlopen
|
109 |
|
|
fails for any reason, it returns NULL.
|
110 |
|
|
A human readable string describing the most recent error that occurred
|
111 |
|
|
from any of the dl routines (dlopen, dlsym or dlclose) can be
|
112 |
|
|
extracted with
|
113 |
|
|
.BR dlerror() .
|
114 |
|
|
.B dlerror
|
115 |
|
|
returns NULL if no errors have occurred since initialization or since
|
116 |
|
|
it was last called. (Calling
|
117 |
|
|
.B dlerror()
|
118 |
|
|
twice consecutively, will always result in the second call returning
|
119 |
|
|
NULL.)
|
120 |
|
|
|
121 |
|
|
.B dlsym
|
122 |
|
|
takes a "handle" of a dynamic library returned by dlopen and the null
|
123 |
|
|
terminated symbol name, returning the address where that symbol is
|
124 |
|
|
loaded. If the symbol is not found,
|
125 |
|
|
.B dlsym
|
126 |
|
|
returns NULL; however, the correct way to test for an error from
|
127 |
|
|
.B dlsym
|
128 |
|
|
is to save the result of
|
129 |
|
|
.B dlerror
|
130 |
|
|
into a variable, and then check if saved value is not NULL.
|
131 |
|
|
This is because the value of the symbol could actually be NULL.
|
132 |
|
|
It is also necessary to save the results of
|
133 |
|
|
.B dlerror
|
134 |
|
|
into a variable because if
|
135 |
|
|
.B dlerror
|
136 |
|
|
is called again, it will return NULL.
|
137 |
|
|
.PP
|
138 |
|
|
.B dladdr
|
139 |
|
|
returns information about the shared library containing the memory
|
140 |
|
|
location specified by
|
141 |
|
|
.IR address .
|
142 |
|
|
.B dladdr
|
143 |
|
|
returns zero on success and non-zero on error.
|
144 |
|
|
.PP
|
145 |
|
|
.B dlclose
|
146 |
|
|
decrements the reference count on the dynamic library handle
|
147 |
|
|
.IR handle .
|
148 |
|
|
If the reference count drops to zero and no other loaded libraries use
|
149 |
|
|
symbols in it, then the dynamic library is unloaded. If the dynamic
|
150 |
|
|
library exports a routine named
|
151 |
|
|
.BR _fini ,
|
152 |
|
|
then 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
|
159 |
|
|
|
160 |
|
|
int 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
|
169 |
|
|
If this program were in a file named "foo.c", you would build the program
|
170 |
|
|
with the following command:
|
171 |
|
|
.RS
|
172 |
|
|
.LP
|
173 |
|
|
gcc -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
|
182 |
|
|
#include
|
183 |
|
|
|
184 |
|
|
int 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
|
208 |
|
|
The dlopen interface standard comes from Solaris.
|
209 |
|
|
The Linux dlopen implementation was primarily written by
|
210 |
|
|
Eric Youngdale with help from Mitch D'Souza, David Engel,
|
211 |
|
|
Hongjiu Lu, Andreas Schwab and others.
|
212 |
|
|
The 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 .
|