| Rev | Author | # | Line |
|---|---|---|---|
| 1 | perry | 1 | !!!DLOPEN |
| 4 | JohnMcPherson | 2 | |
| 1 | perry | 3 | ---- |
| 4 | !!NAME | ||
| 5 | |||
| 6 | |||
| 7 | dlclose, dlerror, dlopen, dlsym - Programming interface to dynamic linking loader. | ||
| 8 | !!SYNOPSIS | ||
| 9 | |||
| 10 | |||
| 4 | JohnMcPherson | 11 | __#include __ <dlfcn.h> |
| 1 | perry | 12 | |
| 13 | |||
| 4 | JohnMcPherson | 14 | void *dlopen (const char *__''filename''__, int__ ''flag''__); |
| 15 | |||
| 1 | perry | 16 | const char *dlerror(void); |
| 4 | JohnMcPherson | 17 | |
| 18 | void *dlsym(void *__''handle''__, char *__''symbol''__); | ||
| 19 | |||
| 20 | int dlclose (void *__''handle''__); | ||
| 1 | perry | 21 | |
| 22 | |||
| 23 | Special symbols: ___init__, ___fini__. | ||
| 24 | !!DESCRIPTION | ||
| 25 | |||
| 26 | |||
| 27 | __dlopen__ loads a dynamic library from the file named by | ||
| 28 | the null terminated string ''filename'' and returns an | ||
| 4 | JohnMcPherson | 29 | opaque "handle" for the dynamic library. If |
| 1 | perry | 30 | ''filename'' is not an absolute path (i.e., it does not |
| 4 | JohnMcPherson | 31 | begin with a "/"), then the file is searched for in the following locations: |
| 1 | perry | 32 | |
| 4 | JohnMcPherson | 33 | ;:A colon-separated list of directories in the user's __LD_LIBRARY_PATH__ environment variable. |
| 1 | perry | 34 | |
| 35 | |||
| 4 | JohnMcPherson | 36 | ;:The list of libraries cached in ''/etc/ld.so.cache''. |
| 1 | perry | 37 | |
| 38 | |||
| 4 | JohnMcPherson | 39 | ;:''/usr/lib'', followed by ''/lib''. |
| 1 | perry | 40 | |
| 41 | |||
| 42 | If ''filename'' is a NULL pointer, then the returned | ||
| 43 | handle is for the main program. | ||
| 44 | |||
| 45 | |||
| 46 | External references in the library are resolved using the | ||
| 47 | libraries in that library's dependency list and any other | ||
| 48 | libraries previously opened with the __RTLD_GLOBAL__ | ||
| 4 | JohnMcPherson | 49 | flag. If the executable was linked with the flag "-rdynamic", |
| 50 | then the global symbols in the executable will | ||
| 51 | also be used to resolve references in a dynamically loaded library. | ||
| 52 | |||
| 1 | perry | 53 | |
| 54 | |||
| 55 | ''flag'' must be either __RTLD_LAZY__, meaning resolve | ||
| 56 | undefined symbols as code from the dynamic library is | ||
| 57 | executed, or __RTLD_NOW__, meaning resolve all undefined | ||
| 58 | symbols before __dlopen__ returns, and fail if this | ||
| 59 | cannot be done. Optionally, __RTLD_GLOBAL__ may be or'ed | ||
| 60 | with ''flag,'' in which case the external symbols defined | ||
| 61 | in the library will be made available to subsequently loaded | ||
| 62 | libraries. | ||
| 63 | |||
| 64 | |||
| 65 | If the library exports a routine named ___init__, then | ||
| 66 | that code is executed before dlopen returns. If the same | ||
| 67 | library is loaded twice with __dlopen()__, the same file | ||
| 68 | handle is returned. The dl library maintains link counts for | ||
| 69 | dynamic file handles, so a dynamic library is not | ||
| 70 | deallocated until __dlclose__ has been called on it as | ||
| 71 | many times as __dlopen__ has succeeded on | ||
| 72 | it. | ||
| 73 | |||
| 74 | |||
| 75 | If __dlopen__ fails for any reason, it returns NULL. A | ||
| 76 | human readable string describing the most recent error that | ||
| 77 | occurred from any of the dl routines (dlopen, dlsym or | ||
| 78 | dlclose) can be extracted with __dlerror()__. | ||
| 79 | __dlerror__ returns NULL if no errors have occurred since | ||
| 80 | initialization or since it was last called. (Calling | ||
| 81 | __dlerror()__ twice consecutively, will always result in | ||
| 82 | the second call returning NULL.) | ||
| 83 | |||
| 84 | |||
| 4 | JohnMcPherson | 85 | __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, |
| 1 | perry | 86 | __dlsym__ returns NULL; however, the |
| 87 | correct way to test for an error from __dlsym__ is to | ||
| 88 | save the result of __dlerror__ into a variable, and then | ||
| 89 | check if saved value is not NULL. This is because the value | ||
| 90 | of the symbol could actually be NULL. It is also necessary | ||
| 91 | to save the results of __dlerror__ into a variable | ||
| 92 | because if __dlerror__ is called again, it will return | ||
| 93 | NULL. | ||
| 94 | |||
| 4 | JohnMcPherson | 95 | |
| 96 | There are two special pseudo‐handles, RTLD_DEFAULT and RTLD_NEXT. The former will find the first occurrence of the desired symbol using the | ||
| 97 | default library search order. The latter, which is usable only from | ||
| 98 | within a dynamic library, will find the next occurrence of a function | ||
| 99 | in the search order after the current library. This allows one to provide a wrapper around a function in another shared library. | ||
| 1 | perry | 100 | |
| 101 | __dlclose__ decrements the reference count on the dynamic | ||
| 102 | library handle ''handle''. If the reference count drops | ||
| 103 | to zero and no other loaded libraries use symbols in it, | ||
| 104 | then the dynamic library is unloaded. If the dynamic library | ||
| 105 | exports a routine named ___fini__, then that routine is | ||
| 106 | called just before the library is unloaded. | ||
| 107 | |||
| 4 | JohnMcPherson | 108 | |
| 109 | !!RETURN VALUE | ||
| 1 | perry | 110 | |
| 111 | __dlclose__ returns 0 on success, and non-zero on | ||
| 112 | error. | ||
| 4 | JohnMcPherson | 113 | |
| 1 | perry | 114 | !!EXAMPLE |
| 115 | |||
| 4 | JohnMcPherson | 116 | __Load the math library, and print the cosine of 2.0:__ |
| 1 | perry | 117 | |
| 118 | |||
| 4 | JohnMcPherson | 119 | #include <stdio.h> |
| 120 | #include <dlfcn.h> | ||
| 1 | perry | 121 | |
| 4 | JohnMcPherson | 122 | int main(int argc, char **argv) { |
| 123 | void *handle; | ||
| 124 | double (*cosine)(double); | ||
| 125 | char *error; | ||
| 1 | perry | 126 | |
| 4 | JohnMcPherson | 127 | handle = dlopen ("/lib/libm.so", RTLD_LAZY); |
| 128 | if (!handle) { | ||
| 129 | fputs (dlerror(), stderr); | ||
| 130 | exit (1); | ||
| 131 | } | ||
| 1 | perry | 132 | |
| 4 | JohnMcPherson | 133 | cosine = dlsym(handle, "cos"); |
| 134 | if ((error = dlerror()) != NULL) { | ||
| 135 | fprintf (stderr, "%s\n", error); | ||
| 136 | exit (1); | ||
| 137 | } | ||
| 1 | perry | 138 | |
| 4 | JohnMcPherson | 139 | printf ("%f\n", (*cosine)(2.0)); |
| 140 | dlclose(handle); | ||
| 141 | } | ||
| 142 | |||
| 143 | |||
| 144 | If this program were in a file named "foo.c", you would build the program with the following command: | ||
| 145 | |||
| 146 | gcc -rdynamic -o foo foo.c -ldl | ||
| 1 | perry | 147 | |
| 148 | !!ACKNOWLEDGEMENTS | ||
| 149 | |||
| 150 | |||
| 151 | The dlopen interface standard comes from Solaris. The Linux | ||
| 152 | dlopen implementation was primarily written by Eric | ||
| 153 | Youngdale with help from Mitch D'Souza, David Engel, Hongjiu | ||
| 154 | Lu, Andreas Schwab and others. The manual page was written | ||
| 155 | by Adam Richter. | ||
| 4 | JohnMcPherson | 156 | |
| 1 | perry | 157 | !!SEE ALSO |
| 158 | |||
| 159 | |||
| 3 | PerryLorier | 160 | ld(1), ld.so(8), ldconfig(8), ldd(1), __ld.so.info__, dladdr(3) |
| 1 | perry | 161 | ---- |
lib/blame.php:177: Warning: Invalid argument supplied for foreach() (...repeated 6 times)