An application can extend its address space during execution by binding to additional shared objects. There are several advantages in this delayed binding of shared objects:
Processing a shared object when it is required, rather than during the initialization of an application, may greatly reduce start-up time. Also, the shared object may not be required during a particular run of the application, for example, objects containing help or debugging information.
The application may choose between a number of different shared objects depending on the exact services required; for example, networking protocols.
Any shared objects added to the process address space during execution may be freed after use.
The following is a typical scenario that an application may perform to access an additional shared object:
A shared object is located and added to the address space of a running application using dlopen(3DL). Any dependencies of shared object are also located and added at this time. For example:
#include <stdio.h> #include <dlfcn.h> main(int argc, char ** argv) { void * handle; ..... if ((handle = dlopen("foo.so.1", RTLD_LAZY)) == NULL) { (void) printf("dlopen: %s\n", dlerror()); exit (1); } .....
The added shared objects are relocated and any initialization sections in the new shared objects are called.
The application locates symbols in the added shared objects using dlsym(3DL). The application can then reference the data or call the functions defined by these new symbols. Continuing the preceding example:
if (((fptr = (int (*)())dlsym(handle, "foo")) == NULL) || ((dptr = (int *)dlsym(handle, "bar")) == NULL)) { (void) printf("dlsym: %s\n", dlerror()); exit (1); }
After the application has finished with the shared objects, the address space is freed using dlclose(3DL). Any termination sections within the shared objects being freed are called at this time. For example:
if (dlcose (handle) != 0) { (void) printf("dlclose: %s\n", dlerror()); exit (1); }
Any error conditions that occur as a result of using these runtime linker interface routines can be displayed using dlerror(3DL).
The services of the runtime linker are defined in the header file <dlfcn.h> and are made available to an application by the shared library libdl.so.1. For example:
$ cc -o prog main.c -ldl |
Here the file main.c can refer to any of the dlopen(3DL) family of routines, and the application prog will be bound to these routines at runtime.
For a thorough discussion of application directed runtime linking, see the Linker and Libraries Guide. See dladdr(3DL), dlclose(3DL), dlerror(3DL), dlopen(3DL), and dlsym(3DL) for use details.